This code
beforeEach(() => {
this.asd= '123';
this.sdf= '234';
this.dfg= '345';
this.fgh= '456';
});
has been transpiled by Babel to:
beforeEach(function() {
undefined.asd= '123';
undefined.sdf= '234';
undefined.dfg= '345';
undefined.fgh= '456';
});
Why?
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.
I had this issue, and changed my fat arrow function into a normal function, and it seemed to work again.
() => {}
changed to
function() {}
Arrow functions don't have their own this
or arguments binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function, this
and arguments refer to the values of this
and arguments in the environment the arrow function is defined in (i.e. "outside" the arrow function).
In your scenario, this
at global scope is undefined. At compile-time, babel will transpile this
within the arrow function as undefined
.
If you are not very familiar with this, consider reading
- MDN - this YDKJS
- this & Object prototypes