繁体   English   中英

摩卡测试中以下js箭头功能中的“ this”指向什么?

[英]What does `this` point at in the following js arrow functions in mocha tests?

什么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在上面的代码如果同时this相同的对象(或多个)点?

UPDATE

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)

在您查询的两个位置中, 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的值转储到控制台,因为如错误消息所示,它是一个带有循环引用的结构。

这是一个很好的问题,因为很多箭头功能教程中都没有解决。

箭头函数在定义时绑定了“ 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⚠将取代thisundefined

"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 };
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM