【问题标题】:Babel replaces this with undefinedBabel 将其替换为 undefined
【发布时间】:2015-12-22 12:36:41
【问题描述】:

这段代码

beforeEach(() => {
        this.asd= '123';
        this.sdf= '234';
        this.dfg= '345';
        this.fgh= '456';
});

已被 Babel 转译为:

beforeEach(function() {
        undefined.asd= '123';
        undefined.sdf= '234';
        undefined.dfg= '345';
        undefined.fgh= '456';
});

为什么?

【问题讨论】:

    标签: javascript jasmine babeljs


    【解决方案1】:

    推测该代码位于模块的顶级范围内,因此它处于严格模式(模块的默认值为严格模式),或者正在以严格模式评估的文件(因为它具有"use strict"或者因为 Babel 的默认值)。

    简短版本:如果您希望在调用回调时 thisbeforeEach 确定,则您需要使用 function 函数,而不是箭头函数。继续阅读为什么 Babel 会按原样进行转换:

    箭头函数的基本特征(除了简洁之外)是它们从上下文继承this(就像它们关闭的变量一样),而不是由调用者设置。在严格模式下,全局范围内的thisundefined。所以 Babel 在编译时知道箭头函数中的 this 将是 undefined 并对其进行优化。

    您在 cmets 中说过这是在另一个函数中,但我猜它在另一个箭头函数中,例如:

    describe(() => {
        beforeEach(() => {
            this.asd= '123';
            // ...
        });
    });
    

    由于 Babel 在describe 回调中知道thisundefined,它知道在beforeEach 回调中thisundefined

    如果您将代码置于松散模式上下文中,或在无法在编译时确定 this 的函数调用中,则不会这样做。例如,在严格模式下你的

    beforeEach(() => {
      this.asd= '123';
      this.sdf= '234';
      this.dfg= '345';
      this.fgh= '456';
    });
    

    确实转换为

    'use strict';
    beforeEach(function () {
      undefined.asd = '123';
      undefined.sdf = '234';
      undefined.dfg = '345';
      undefined.fgh = '456';
    });
    

    但是这个:

    function foo() {
      beforeEach(() => {
        this.asd= '123';
        this.sdf= '234';
        this.dfg= '345';
        this.fgh= '456';
      });
    }
    

    转译为

    'use strict';
    
    function foo() {
      var _this = this;
    
      beforeEach(function () {
        _this.asd = '123';
        _this.sdf = '234';
        _this.dfg = '345';
        _this.fgh = '456';
      });
    }
    

    ...因为 Babel 不知道 foo 将如何被调用,因此 this 将是什么。

    【讨论】:

    • 此代码位于嵌套的describe 块内,因此它位于闭包中,而不是全局级别。它必须工作正常吗?
    • @mms27:显示代码。我们无法为您提供我们看不到的代码。如果这段代码在一个用箭头语法定义的函数的回调中,那么它与上面的问题相同,只是嵌套了。
    • 明白了!是的,这很可能是这种情况。我可能应该避免使用箭头函数,而是使用常规匿名函数。
    • @mms27:如果您希望thisbeforeEach 设置,那么是的,回调不能是箭头函数,因为beforeEach 无法控制@ 987654348@ 由箭头函数使用。这是箭头函数的基本属性:它们从上下文继承this(就像它们关闭的变量一样),而不是由调用者设置。
    【解决方案2】:

    我遇到了这个问题,把我的粗箭头函数改成普通函数,它似乎又可以工作了。

    () => {} 
    

    改为

    function() {}
    

    【讨论】:

      【解决方案3】:

      箭头函数没有自己的this 或参数绑定。相反,这些标识符像任何其他变量一样在词法范围内解析。这意味着在箭头函数内部,this 和 arguments 指的是 this 的值和定义箭头函数的环境中的参数(即箭头函数的“外部”)。
      在您的场景中,全局范围内的 this 未定义。在编译时,babel 会将箭头函数内的this 转换为undefined

      如果你对此不是很熟悉,可以考虑阅读

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-14
        • 2020-02-09
        • 1970-01-01
        • 1970-01-01
        • 2016-06-22
        • 1970-01-01
        • 2019-02-11
        相关资源
        最近更新 更多