What does this
point here?
const expect = require('chai').expect;
const sinon = require('sinon');
describe('test', () => {
describe('test()', () => {
afterEach(function _test() {
this.xxx = undefined; // What does `this` point here?
});
});
describe('test2()', () => {
afterEach(function _test2() {
this.yyy = undefined; // What does `this` point here?
});
});
});
By the way, it is good to use this
in the above codes if both this
(s) point at the same object?
UPDATE
Code
describe('test', () => {
console.log(1, this);
before(() => {
console.log(2, this);
});
beforeEach( () => {
console.log(3, this);
});
describe('going deeper', () => {
console.log(4, this);
beforeEach(() => {
console.log(6, this);
});
return it('has increased someVal to 3', function() {
assert.equal(1,1);
//console.log(7, this);
});
});
});
output:
1 {}
4 {}
test
2 {}
going deeper
3 {}
6 {}
✓ has increased someVal to 3
1 passing (4ms)
code (changed one arrow function to normal function):
describe('test', () => {
console.log(1, this);
before(() => {
console.log(2, this);
});
beforeEach( () => {
console.log(3, this);
});
describe('going deeper', () => {
console.log(4, this);
beforeEach(function() { // HERE
console.log(6, this);
});
return it('has increased someVal to 3', function() {
assert.equal(1,1);
//console.log(7, this);
});
});
});
output:
1 {}
4 {}
test
2 {}
going deeper
3 {}
1) "before each" hook for "has increased someVal to 3"
0 passing (6ms)
1 failing
1) test going deeper "before each" hook for "has increased someVal to 3":
TypeError: Converting circular structure to JSON
at Object.stringify (native)
at formatValue (util.js:352:36)
at inspect (util.js:186:10)
at exports.format (util.js:72:24)
at Console.log (console.js:43:37)
at Context.<anonymous> (test3.js:32:15)
In both locations you inquire about, this
is bound by Mocha to an internal Mocha object. One thing this object allows you to do, for instance, is change Mocha's configuration. Like changing the timeout of asynchronous function with this.timeout(newValue)
. It's not particularly useful in the example below, but Mocha will run it just fine. Eg:
describe('test', () => {
describe('test()', () => {
afterEach(function _test() {
this.timeout(5000);
this.xxx = undefined;
});
it("foo", () => {});
});
describe('test2()', () => {
afterEach(function _test2() {
this.timeout(5000);
this.yyy = undefined;
});
it("foo", () => {});
});
});
Note that if you were to use an arrow function for your afterEach
callbacks, you could not access the value of this
that Mocha sets for the callback. ( this
will have a value set in an outer scope.)
By the way, it is good to use this in the above codes if both this(s) point at the same object?
I don't recommend setting arbitrary fields on this
. There's no telling when the field you set is going to clash with a field introduced by a newer version of Mocha. I've always been able instead to set a variable in the enclosing describe
and use that:
describe('test', () => {
let something;
beforeEach(function _test() {
something = fetchATestFixtureFromSomewhere();
});
it("foo", () => {
// use the variable something here.
});
});
Regarding your update. Everywhere you get {}
on the console that's because all functions enclosing your console.log
are arrow functions and as I've said above, if you use an arrow function then you cannot access the object that Mocha binds to this
because in such case this
is taken from an outer scope instead of being taken from the value bound to the function. If all enclosing functions are arrow functions then this
comes from the outermost scope and it has the value {}
in the outermost scope.
The error you get is because you cannot just dump the value Mocha assigns to this
to the console, because as the error message indicates, it is a structure with a circular reference in it.
This is a good question because it is something that is not addressed in a lot of arrow function tutorials.
Arrow functions have there "this" context bound at definition time, but more importantly your question. The this will inherit recursively.
describe('test', () => { // `this` is the global object
describe('test()', () => { // `this` is the global object
afterEach(function _test() {
this.xxx = undefined; // `this` is the global object
});
});
describe('test2()', () => { // `this` is the global object
afterEach(function _test2() {
this.yyy = undefined; // `this` is the global object
});
});
});
Here is an example
const foo = ()=>{ console.log("foo is window?",this === window); const a = (input)=>{console.log("a is window?",this === window); this._=input }; const b = ()=> {console.log("b is window?",this === window);return this._} return { a,b } } const bar= foo() console.log(bar.b()) // undefined bar.a(5) console.log(bar.b()) // 5 console.log(window._) // 5
if you change
const b = ()=> {console.log("b is window?",this === window);return this._}
to
const b = function() {console.log("b is window?",this === window);return this._}
the this
now points to the wrapping Object { a,b }
If you use an ES6 to ES5 ⚠ will replace this
with undefined
"use strict"; // https://es6console.com/
var foo = function foo() {
console.log("foo is window?", undefined === window);
var a = function a(input) {
console.log("a is window?", undefined === window);undefined._ = input;
};
var b = function b() {
console.log("b is window?", undefined === window);return undefined._;
};
return { a: a, b: b };
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.