除箭头函数外函数的this在其执行时才被确定,指向其调用者。
1. 当函数作为方法被调用时指向它的调用者
例如
let obj = {
a: 2,
b: function() {
console.log(this);
console.log(this.a);
}
}
let fn = obj.b;
obj.b(); //obj 2
fn(); //window undefined 等价window.fn()
第一种情况下该函数是被obj对象调用的,this指向obj对象
第二种情况下该函数是被window对象调用的,this指向window对象
2. 当函数作为函数被直接调用时指向window对象
例如
let obj = {
a: 2,
b: function() {
console.log(this);
console.log(this.a);
fn();
}
}
function fn() {
console.log(this);
console.log(this.a);
}
obj.b();// obj, 2; window, undefined
当一个函数被另一个函数嵌套调用时该函数指向window对象,可以理解为只要函数是直接调用,其this都是指向window的(箭头函数除外),要注意分this和变量不一样,变量会从上一层的执行上下文继承,而this不会。
3. 箭头函数的this指向
箭头函数的this在定义时就被确定了,箭头函数没有自己的 this 值,箭头函数中所使用的 this 都是来自函数作用域链,箭头函数中的this从上层作用域寻找。
当箭头函数被其他函数包含时
function fn() {
let a = 1;
return () => {
console.log(this);
console.log(this.a);
}
}
let obj = {
b: 10,
c: function() {
return () => {
console.log(this);
console.log(this.b);
}
}
};
//output
fn()();//window, undefined
fn.apply(obj)();//obj, undefined
fn.apply()(obj);//window, undefined
obj.c()();//obj, 10
第一种情况fn中的this是指向window的,所以箭头函数的this和fn中的this一样也指向window
第二种情况下将fn执行此时fn中this的指向被apply修改为obj,所以箭头函数的this也指向obj 第三种情况箭头函数的this在其定义时就确定了,所以apply无法改变箭头函数的this指向
第四种情况c中函数的this指向obj,所以箭头函数的this指向也指向obj
当箭头函数作为对象的属性值时
let a = 1;
let obj = {
a: 2,
b: () => {
console.log(this);
console.log(this.a);
},
c: {
a: 3,
d: () => {
console.log(this);
console.log(this.a);
}
}
}
obj.b(); // window, undefined
obj.c.d(); // window, undefined
由于对象是作为对象字面量的属性定义的,对象字面量在全局代码中定义,因此,箭头函数内部的this值与全局函数的this值相同
我的理解是这样的
obj.c.d = () => {
console.log(this);
console.log(this.a);
}
可以从代码结构上看到箭头函数并未被其他{}包含,所以其外层作用域中的this就是全局的window
简单总结为如果箭头函数被非箭头函包含,则this绑定指向的是最近一层非箭头函数的this,否则,this的值会被设置为全局对象。