Babel replaces this with undefined

前端 未结 3 1696
[愿得一人]
[愿得一人] 2021-02-18 15:47

This code

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

3条回答
  •  日久生厌
    2021-02-18 16:16

    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).

    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:

    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';
            // ...
        });
    });
    

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

    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';
    });
    

    does indeed transpile to

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

    but this:

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

    transpiles to

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

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

提交回复
热议问题