原链接:www.30secondsofcode.org/articles/s/…
什么是this?
在javaScript中,this关键词指向了正在执行代码的对象,可以简单总结如下:
- 默认情况下,
this指向全局对象global object; - 非严格模式下,普通函数中的
this指向全局对象global object; - 严格模式下,普通函数中的
this为undefined; - 箭头函数中,
this的指向与其词法上下文环境中的this保持一致; - 对象函数中,
this指向了调用该方法的对象; - 构造函数中,
this指向(绑定,binding)正在新建的对象; - 事件回调函数中,
this指向了(绑定,binding)放置监听函数的元素;
全局上下文Global Context
在全局执行上下文,this指向全局对象global object
console.log(this === window); // true
函数上下文Function Context
非严格模式下,函数this指向全局对象
function f() {
return this;
}
console.log(f() === window); // true
严格模式下,若没有设置执行上下文,函数中的this为undefined
'use strict';
function f() {
return this;
}
console.log(f()); // undefined
对象上下文Object Context
当调用对象函数时,this指向调用该函数的对象Caller Object,指向对象可以定位在原型链上任何位置(原生或继承方法)
const obj = {
f: function() {
return this;
}
};
const myObj = Object.create(obj);
myObj.foo = 1;
console.log(myObj.f()); // { foo: 1 }
当对象函数是构造函数constructor时,this指向新建对象
class C {
constructor() {
this.x = 10;
}
}
const obj = new C();
console.log(obj.x); // 10
箭头函数上下文Arrow Function Context
在箭头函数中,this指向封闭词法上下文中的this
const f = () => this;
console.log(f() === window); // true
const obj = {
foo: function() {
const baz = () => this;
return baz();
},
bar: () => this
};
console.log(obj.foo()); // { foo, bar }
console.log(obj.bar() === window); // true
注意console.log(obj.bar() === window); // true,this指向了全局对象window而不是obj,并没有像对象函数中的this,指向调用方;
事件回调上下文Event Handler Context
当在DOM元素中绑定一个事件回调函数时,函数this指向了绑定该监听器的DOM元素
const el = document.getElementById('my-el');
el.addEventListener('click', function() {
console.log(this === el); // true
});
el.addEventListener('click', () => {
console.log(this === el); // false
});
注意() => { console.log(this === el); // false },箭头函数仍指向了全局对象window,其事件回调函数是箭头函数,而不是普通函数;
绑定this
使用Function.prototype.bind(),从已有的函数返回一个新的函数,其this永久绑定bind()传入的第一个参数对象
function f() {
return this.foo;
}
var x = f.bind({foo: 'hello'});
console.log(x()); // 'hello'
也可以用Function.prototype.call()或者Function.prototype.apply(),其也会绑定this至传入的第一个参数,但不会返回一个新的函数,只在本次调用生效;
function f() {
return this.foo;
}
console.log(f.call({foo: 'hi'})); // 'hi'