this的指向只取决于如何调用
有4种情况
new method() this 指向新对象function Foo() { console.log(this.name) }
const f = new Foo()
// this 指向 f 这个实例
method() 指向全局对象function foo() { console.log(this.name) }
foo()
// this 指向全局(window 或者 global)
obj.method() 指向前面的对象const obj = {
name: "jack",
say: function() {
console.log(this.name)
}
}
obj.say() // jack
method.call(ctx) 指向第一个参数 ctxconst c = {
name: '123'
}
const obj = {
name: '456'
}
function printName() {
console.log(this.name)
}
printName.call(c) // '123'
printName.apply(obj) // '456'
const n = printName.bind(obj)
n() // '456'
箭头函数没有this, this 在箭头函数定义的时候就确定好了,就是定义箭头函数所在的执行上下文,且不可通过 call apply bind 改变
const outerThis = { name: '外部' };
const obj = {
name: '内部',
arrowFunc: () => {
console.log(this.name);
},
normalFunc: function() {
console.log(this.name);
}
};
// 这是全局环境,this的undefind
const calculator = {
value: 10,
// 传统写法需要保存 this
traditionalMethod: function() {
const self = this;
return {
double: function() {
return self.value * 2;
}
};
},
// 箭头函数简化代码
arrowMethod: function() {
return {
double: () => {
// 这里的的执行上下文是 arrowMethod这个函数,所以 this 指向 arrowMethod的this,即这个 calculator 对象
return this.value * 2; // 自动捕获外层的 this
}
};
}
};
new绑定 > 显式绑定(call apply bind) > 隐式绑定 > 默认绑定
// 优先级示例
function test() {
console.log(this.name);
}
const obj1 = { name: 'obj1' };
const obj2 = { name: 'obj2' };
// 显式绑定优先级高于隐式绑定
obj1.test = test;
obj1.test.call(obj2); // 'obj2'
// new绑定优先级最高
const boundTest = test.bind(obj1);
const instance = new boundTest(); // this指向新实例