Babel 将其替换为 undefined

2022-01-11 00:00:00 jasmine javascript babeljs

这段代码

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

已被 Babel 转译为:

has been transpiled by Babel to:

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

为什么?

推荐答案

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

Presumably that code is at the top-level scope of a module, and so it's in strict mode (the default for modules is strict mode), or a file that is being evaluated in strict mode (because it has "use strict" or because of Babel's defaults).

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

The short version: If you're expecting this to be determined by beforeEach when calling your callback, you'll want to use a function function, not an arrow function. Read on for why Babel is transpiling as it is:

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

The fundamental thing about arrow functions (other than being concise) is that they inherit this from their context (like a variable they close over), instead of having it set by the caller. In strict mode, this at global scope is undefined. So Babel knows, at compile-time, that this within the arrow function will be undefined and optimizes it.

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

You've said in comments that this is inside another function, but my guess is that it's inside another arrow function, e.g.:

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

由于 Babel 在 describe 回调中知道 thisundefined,它也知道 thisbeforeEach 回调中的 undefined.

Since Babel knows that this is undefined in the describe callback, it also knows that this is undefined in the beforeEach callback.

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

If you put your code in a loose mode context, or inside a function call where this can't be determined at compile-time, it won't do that. For example, in strict mode your

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 将是什么.

...because Babel doesn't know how foo will be called, and thus what this will be.

相关文章