默认绑定
// 适用场合:默认情况下
// 指向规则:非严格模式下this指向全局对象,严格模式下this指向undefined
var a = "a";
function foo() {
console.log(this.a);
}
foo(); // "a"(非严格模式下)
隐式绑定
// 适用场合:调用函数时,有上下文对象
// 指向规则:this指向调用链中的最后一层,即函数的直接调用者
var a = "a",
obj1 = { a: "a1", foo },
obj2 = { a: "a2", obj1, foo };
function foo() {
console.log(this.a);
}
obj1.foo(); // 'a1'
obj2.foo(); // 'a2'
obj2.obj1.foo(); // 'a1'
// 在下面的例子中,虽然bar指向obj1.obj2.foo
// 但在实际调用bar时,未带任何上下文对象
// 所以会导致隐式丢失,并应用默认绑定
var bar = obj2.obj1.foo;
bar(); // 'a'(非严格模式下)
显式绑定
// 适用场合:通过call、bind、bind手动改变了this指向时
// 指向规则:this指向call、apply、bind的第一个参数
var a = "global_a",
b = "global_b",
obj = {
a: "obj_a",
b: "obj_b",
};
function foo(a, b) {
console.log(this.a, this.b, a, b);
}
foo(a, b); // undefined, undefined, global_a, global_b
foo.call(obj, a, b); // obj_a, obj_b, global_a, global_b
foo.apply(obj, [a, b]); // obj_a, obj_b, global_a, global_b
const fooBind = foo.bind(obj);
fooBind(a, b); // obj_a, obj_b, global_a, global_b
new 绑定
// 适用场合:使用new和构造函数创建实例时
// 指向规则:构造函数内的this指向被创建实例
function foo(a) {
this.a = a;
}
var obj = new foo("a"),
console.log(obj.a); // 'a'
箭头函数
// 适用场合:使用箭头函数时
// 指向规则:箭头函数内的this指向定义箭头函数所处环境中的this,即箭头函数外层的this
// 注意,箭头函数内的this指向不能被call、apply、bind等改变
var a = "a",
obj = {
a: "obj",
foo: function () {
console.log(this.a);
(() => {
console.log(this.a);
})();
},
bar: () => {
console.log(this.a);
},
};
obj.foo(); // 'obj', 'obj'
obj.bar(); // 'a'(非严格模式下)