开发者社区> 问答> 正文

如何正确判断this?箭头函数的this是什么?

展开
收起
前端问答 2019-11-24 19:49:04 1198 0
1 条回答
写回答
取消 提交回答
  • 前端问答小助手

    如何判断this指向问题?记住一句话即可:谁调用它,this就指向谁

    先看几个调用场景:

    function foo() {
      console.log(this.a)
    }
    var a = 1
    foo()
    
    const obj = {
      a: 2,
      foo: foo
    }
    obj.foo()
    
    const c = new foo()
    

    分析如下:

    • 对于直接调用foo来说,不管foo函数被放在了什么地方,this一定是window;
    • 对于obj.foo()来说,我们只需要记住,谁调用了函数,谁就是this,所以在这个场景下foo函数中的this就是obj对象;
    • 对于new的方式来说,this被永远绑定在了c上面,不会被任何方式改变this

    箭头函数this

    箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于自己的this,它所谓的this是捕获其所在上下文的this值,作为自己的this值,并且由于没有属于自己的this,箭头函数是不会被new调用的,这个所谓的this也不会被改变, 我们可以用Babel理解⼀下箭头函数:

    // ES6
    const obj = {
      getArrow() {
        return () => {
          console.log(this === obj);
        };
      }
    };
    

    转化后

    // ES5,由 Babel 转译
    var obj = {
      getArrow: function getArrow() {
        var _this = this;
        return function() {
          console.log(_this === obj);
        };
      }
    };
    

    扩展:

    最后种情况也就是bind这些改变上下文的API了,对于这些函数来说,this取决于第一个参数,如果第一个参数为空,那么就是window

    说到bind,不知道大家是否考虑过,如果对一个函数进行多次bind,那么上下文会是什么呢?

    let a = {}
    let fn = function () { console.log(this) }
    fn.bind().bind(a)() // => ?
    

    如果你认为输出结果是a,那么你就错了,其实我们可以把上述代码转换成另一种形式:

    // fn.bind().bind(a) 等于
    let fn2 = function fn1() {
      return function() {
        return fn.apply()
      }.apply(a)
    }
    fn2()
    

    可以从上述代码中发现,不管我们给函数bind几次,fn中的this永远由第一次bind决定,所以结果永远是window

    思考:不同规则下的this最终指向哪里呢?

    首先new的方式优先级最高,接下来是bind这些函数,然后是obj.foo()这种调用方式,最后是foo这种调用方式,同时,箭头函数的this一旦被绑定,就不会再被任何方式所改变。

    图解如下:(针对单个规则)

    image.png

    2019-11-25 06:54:44
    赞同 1 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载