JS中this的指向,箭头函数this的指向

·  阅读 1179

除箭头函数外函数的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的值会被设置为全局对象。

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改