一、this 是什么?
this 是当前运行环境的一个属性,指向最近的对象实例。
二、怎么用?
1、全局
<!DOCTYPE html>
<html lang='zh-CN'>
<head>
<meta charset="utf-8">
<title>this</title>
<script>
// 全局环境下,等同于 window 对象
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b) // "MDN"
console.log(b) // "MDN"
</script>
</head>
<body>
<h1>打开 Console 看结果!</h1>
</body>
</html>
2、函数中this
函数中的this指向调用他的实例对象。
var obj = {a: 'Custom'};
var a = 'Global';
function whatsThis() {
return this.a;
}
// 全局调用,this 指向 window 对象
whatsThis(); // Global
// 强制实例对象obj转换为this
whatsThis.call(obj); // Custom
whatsThis.apply(obj); // Custom
3、方法中this
方法中的 this 是指向最近的对象实例。
var o = {
prop: 37,
f: function () {
return this.prop;
}
};
console.log(o.f()); // 37
o.b = { g: independent, prop: 42 };
// g()方法中最近实例是b,实例o是再上一层实例
console.log(o.b.g()); // 42
4、箭头函数中this
箭头函数本身无法与 this 进行绑定,所以箭头函数中使用的this是指向上层作用域。call、bind、apply 对箭头函数中this无效。
// 1、this 指向上层作用域
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true
// 2、call、bind 无法改变箭头函数中的 this
console.log(foo.call(obj) === globalObject); // true
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
- 方法中使用含有this的箭头函数
var obj = {
bar: function() {
var x = (() => this);
return x;
}
};
// 1、调用方法,this指向对象实例
var fn = obj.bar();
console.log(fn() === obj); // true
// 2、引用方法,this不指向对象实例
var fn2 = obj.bar;
console.log(fn2()() == window); // true
5、原型链上this
原型链上的this也是指向最近对象实例。
var o = {
f: function() {
return this.a + this.b;
}
};
// 对象o是对象p的原型
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f()); // 5
6、set、get中this
set、get方法中的this也是指向最近对象实例。
function sum() {
return this.a + this.b + this.c;
}
var o = {
a: 1,
b: 2,
c: 3,
get average() {
return (this.a + this.b + this.c) / 3;
}
};
Object.defineProperty(o, 'sum', {
get: sum, enumerable: true, configurable: true});
console.log(o.average, o.sum); // logs 2, 6
7、new与this
new 后面的构造函数,如果没有return语句,就会返回this;如果有,就用返回return语句的对象。
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); // logs 37
function C2(){
this.a = 37;
return {a:38};
}
o = new C2();
console.log(o.a); // logs 38
8、DOM中this
如果this用在事件回调函数中,那么this指向触发事件的元素。
// 被调用时,将关联的元素变成蓝色
function bluify(e){
console.log(this === e.currentTarget); // 总是 true
// 当 currentTarget 和 target 是同一个对象时为 true
console.log(this === e.target);
this.style.backgroundColor = '#A5D9F3';
}
// 获取文档中的所有元素的列表
var elements = document.getElementsByTagName('*');
// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色
for(var i=0 ; i<elements.length ; i++){
elements[i].addEventListener('click', bluify, false);
}
9、类中this
- 类方法中this指向调用它的对象实例。
var name = "globalName";
class Example{
name="className";
fun(){
return this.name;
}
}
// 1、this指向实例对象
let exm = new Example();
console.log(exm.fun());
// 2、使用全局this作为实例对象
let funGlobal = Example.fun;
console.log(exm.fun.call(this));
- 使用bind方法,让类方法中this永远指向类的实例
class Car {
constructor() {
this.sayBye = this.sayBye.bind(this);
}
sayHi() {
console.log(`Hello from ${this.name}`);
}
sayBye() {
console.log(`Bye from ${this.name}`);
}
get name() {
return 'Ferrari';
}
}
class Bird {
get name() {
return 'Tweety';
}
}
const car = new Car();
const bird = new Bird();
// 1、不同实例调用不同结果
car.sayHi(); // Hello from Ferrari
bird.sayHi = car.sayHi;
bird.sayHi(); // Hello from Tweety
// 2、绑定this,结果不会改变
bird.sayBye = car.sayBye;
bird.sayBye(); // Bye from Ferrari
- 类中this 包含所有非静态方法,静态方法属于类本身属性。
class Example {
constructor() {
const proto = Object.getPrototypeOf(this);
console.log(Object.getOwnPropertyNames(proto));
}
first() { }
second() { }
static third() { }
}
new Example(); // ['constructor', 'first', 'second']
10、bind()
bind() 方法可以将函数的this 与 某个对象实例进行永久绑定,无需考虑函数的调用方式。已绑定对象无法再次绑定。
function f(){
return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
// 已绑定对象无法再次绑定。
var h = g.bind({a:'yoo'});
console.log(h()); // azerty
var o = {a:37, f:f, g:g, h:h};
console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。