this
指向什么?
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?
});
});
});
顺便说一下,如果this
(s)都指向同一个对象,最好在上面的代码中使用this
吗?
更新
代码
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);
});
});
});
输出:
1 {}
4 {}
test
2 {}
going deeper
3 {}
6 {}
✓ has increased someVal to 3
1 passing (4ms)
代码(将一个箭头功能改为普通功能):
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);
});
});
});
输出:
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)
答案 0 :(得分:3)
在您查询的两个位置,this
被Mocha绑定到内部Mocha对象。例如,这个对象允许你做的一件事就是改变Mocha的配置。比如用this.timeout(newValue)
更改异步函数的超时。它在下面的例子中并不是特别有用,但是Mocha会运行得很好。例如:
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", () => {});
});
});
请注意,如果您使用箭头函数进行afterEach
回调,则无法访问Mocha为回调设置的this
值。 (this
将在外部范围内设置值。)
顺便说一句,如果这两个代码都指向同一个对象,最好在上面的代码中使用它吗?
我不建议在this
上设置任意字段。没有人知道你设置的字段何时会与较新版本的Mocha引入的字段发生冲突。我总是能够在封闭的describe
中设置一个变量并使用它:
describe('test', () => {
let something;
beforeEach(function _test() {
something = fetchATestFixtureFromSomewhere();
});
it("foo", () => {
// use the variable something here.
});
});
关于您的更新。你在控制台上得到{}
的所有地方都是因为包含你console.log
的所有函数都是箭头函数,正如我上面所说,如果你使用箭头函数然后你就无法访问摩卡的对象绑定到this
因为在这种情况下this
取自外部作用域而不是从绑定到函数的值中取出。如果所有封闭函数都是箭头函数,则this
来自最外层范围,并且在最外层范围内具有值{}
。
您得到的错误是因为您不能只将Mocha分配给this
的值转储到控制台,因为正如错误消息所示,它是一个带有循环引用的结构。
答案 1 :(得分:0)
这是一个很好的问题,因为很多箭头功能教程都没有解决这个问题。
箭头函数在定义时绑定了“this”上下文,但更重要的是你的问题。这将以递归方式继承。
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
});
});
});
这是一个例子
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
如果你改变了
const b = ()=> {console.log("b is window?",this === window);return this._}
到
const b = function() {console.log("b is window?",this === window);return this._}
this
现在指向包装对象{ a,b }
如果您使用ES6至ES5,则会将this
替换为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 };
};