暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

JS-箭头函数中的this的指向(笔记转载)

小王学前端 2021-01-16
452

面试宝典之箭头函数中的this

当面试官问ES6你都了解哪些啊?你大概率会说,箭头函数。那么面试官接着问,箭头函数跟function有什么区别啊?然后你又自信满满的说this指向的不同。那么面试官又问,那请说明一个this指向都有哪些不同?这时部分同学会对this的概念表达很模糊,下面就来详细说下箭头函数this指向的问题~

    1.function和箭头函数的this指向有哪些不同?

  1. 要了解箭头函数中的this,先看function中的this优点以及不足,再来看箭头函数的设计会看的比较清晰。

  2. function中的this指向的是使用时所在的对象,而箭头函数中的this指向定义时所在的对象,这点非常重要,举个例子~

  3. function fn(){
    console.log(this);
    };
    fn();

    复制
  4. 请问打印出来的this在浏览器中显示什么?

  5. :应该显示的是fn外层的对象,因为使用者为fn外层的对象,如果fn处在最顶层,那么在浏览器中应该显示window对象,在node.js中应该显示global对象,也就是现在他们的顶级作用域对象。如果在fn的外层是一个function对象,那么就指向function的this。听起来可能有点晕,不过没关系,多举例子就明白了~

    再举个例子

  6. birth =  1994;
    var obj = {
    birth: 2000,
    getAge: function () {
    console.log(this.birth);
    }
    };
    obj.getAge();
    var a = obj.getAge;//2000
    a();//1994

    复制
  7. 那么这两个调用为什么会一个输出2000一个输出1994呢?还是之前的答案,因为function中的this指向的是使用者的对象,第一个使用者为obj对象,所以this当然指向obj。第二个呢,上方birth没有写var 自动赋值给了顶级作用域(当然不推荐大家这样赋值哈,就是做个例子^_^)然后当调用a()的时候其实是顶级对象在调用它,当然this指的是顶级作用域。

  8. 2.function这种动态的this指向哪些弊端能用箭头函数解决?

  9. 所以在某些场景下会使用function就找不到需要的this,比如

  10. class Test {
    constructor() {
    this.birth = 10;
    }
    submit(){
    $.ajax({
    type: "POST",//方法类型
    dataType: "json",//预期服务器返回的数据类型
    url: "xxxxx" ,//url
    data: "xxxxx",
    success: function (result) {
    console.log(this.birth);//undefined
    },
    error : function() {}
    });
    }
    }
    let test = new Test();
    test.submit();//undef

    复制
  11. 这时传统的解决方案这样:把this赋值给一个变量。

  12. class Test {
    constructor() {
    this.birth = 10;
    }
    submit(){
    let self = this;
    $.ajax({
    type: "POST",
    dataType: "json",
    url: "xxxxx" ,//url
    data: "xxxxx",
    success: function (result) {
    console.log(self.birth);//10
    },
    error : function() {}
    });
    }
    }
    let test = new Test();
    test.submit();//undefined

    复制

通过this赋值给一个变量,然后再通过变量访问。

这时箭头函数的第一个优势就出来了,因为箭头函数中的this指向的是定义时的对象这时箭头函数定义时的对象为 Test类的实例对象,也就是test对象,所以this能找到birth属性。

...
success: (result)=> {
console.log(this.birth);//10
},
...

复制

3.普通函数动态this指向优势有哪些?

当然function函数这种动态的this指向有他的好处,就是可以自由的指向对象,比如js中call或者apply方法可以动态指定function中的this对象,如果没有call或者apply方法,则是指向调用者的对象。

birth =  1994;
var obj = {
birth: 2000,
getAge: function () {
console.log(this.birth);
}
};
var obj2 = {
birth: 2018;
};
var a = obj.getAge;
a();//1994
a.call(obj);//2000
a.call(obj2);//2018

复制

如果使用箭头函数会这样,看下面例子

birth =  1994;
var obj = {
birth: 2000,
getAge: ()=> {
console.log(this.birth);
}
};
var obj2 = {
birth: 2018;
};
var a = obj.getAge;
a();//1994
a.call(obj);//1994
a.call(obj2);//1994

复制

在浏览器中定义箭头函数的的调用对象为window,所以不用使用什么方法,它的this对象指向的都是window对象,所以call或者apply对箭头函数不起作用,因为箭头函数一旦被调用者定义就不会改变。

3.箭头函数中的this的使用场景

下面的例子function和箭头函数混合使用,先用function函数在确定this指向,然后查看下面箭头函数this指向。

function foo() {
setTimeout(() => {
console.log(this.id);
}, 100);
}

id = 21;
foo.call({ id: 12 });//12

复制

外层foo函数确认指向的是一个{ id:12}对象,然后它下面的箭头函数作为setTimeout的回调函数,其定义时上下文的this对象,也就是foo函数的this,所以foo函数的this指向哪里就是哪里,如果把箭头函数变为普通函数,那么虽然定义时调用者为foo,但是实际100ms后真正使用这个函数的时window对象。如下~

function foo() {
setTimeout(function (){
console.log(this.id);
}, 100);
}
id = 21;
foo.call({ id: 12 });//21

复制

所以在箭头函数中this指向的这个特性非常在回调函数中的应用。

4.扩展-箭头函数跟普通函数的区别都有哪些?

  1. 函数体内的this
    对象,就是定义时所在的对象,而不是使用时所在的对象。当对箭头函数使用call()和apply()方法时对函数内的this没有影响。

  2. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

  3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  4. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

  5. 箭头函数没有原型属性。

注意:当写代码中使用的都是同一个变量时,如果拿不到值的话,那么记得看一下当前的this调用,是在普通函数中使用还是箭头函数中使用,要想在多个方法中都同时对一个变量进行操作,那么就在箭头函数中使用,()=>{console.log(this.pipColData)}。一定要用箭头函数,当时我保存拿不到值,就是this的指向不对,纠结了好久,所以总结了这些,希望以后大家也不要到再犯这个错误了。


文章转载自小王学前端,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论