有没有办法在使用ES6速记方法表示法的方法中使用词汇“this”?

时间:2017-02-19 07:08:41

标签: javascript methods ecmascript-6 this bind

关于SO的第一个问题,我希望我不会重复任何事情;我看了other questions,认为我的不同,不值得问。

基本上,有没有办法让使用简写表示法编写的方法的方法体中的this是词法还是绑定到特定值?

这样做的动机来自于我在实现iterator protocol时想要使用ES6方法的简写,其中@@iterator方法在被调用时返回迭代器对象。该迭代器对象必须具有next()方法,该方法在被调用时返回另一个对象。我希望在第二个对象中引用原始(在我的情况下,Graph)实例。

请注意,在下面的代码段中,由于this绑定,按预期工作,next()正在使用ES6 method definition shorthand

class Graph {
  constructor(initialNodes) {
    this.data = [...initialNodes];
  }

  [Symbol.iterator]() {
    let nextIndex = 0;
    // `this` binding is fine here, as expected
    return {
      // look at that beautiful shorthand
      next() {
        return nextIndex < this.data.length
          // `this` binding is not fine here
          ? { done: false, value: this.data[nextIndex++] }
          : { done: true };
      }
    };
  }
}

我知道在对象返回上面定义函数,然后将该函数指定为被返回对象的属性,但我又想知道是否可以使用方法简写语法。

将返回对象上方的next()定义为常规函数,然后将其绑定到对象属性赋值中:

class Graph {
  // constructor

  [Symbol.iterator]() {
    let nextIndex = 0;
    // I know you can do this
    const next = function() {
      return nextIndex < this.data.length
        ? { done: false, value: this.data[nextIndex++] }
        : { done: true };
    };
    return {
      next: next.bind(this)
    };
  }
}

将箭头函数定义在返回对象上方next()意味着不需要bind,但仍然没有方法语法简写:

class Graph {
  // constructor

  [Symbol.iterator]() {
    let nextIndex = 0;
    // I know you can also do this
    const next = () => {
      return nextIndex < this.data.length
        ? { done: false, value: this.data[nextIndex++] }
        : { done: true };
    };
    return {
      next
    };
  }
}

Icepickle在评论中提出了一个很好的观点,我可以使用它存储this上下文并在速记方法体中引用它。我假设这是我能得到的最接近的?

class Graph {
  // constructor

  [Symbol.iterator]() {
    let nextIndex = 0;
    const self = this;
    return {
      next() {
        return nextIndex < self.data.length
          ? { done: false, value: self.data[nextIndex++] }
          : { done: true };
      }
    };
  }
}

1 个答案:

答案 0 :(得分:1)

解决问题的理想方法是使用适当的工具:generator function。它们也可以与shorthand syntax一起使用,它们将正确绑定 ol { counter-reset: item } ol li { display: block } ol li:before { content: counters(item, ".") ". "; counter-increment: item } ol[style*="list-style-type: lower-alpha;"] li:before { content: counters(item, ".", lower-alpha) ". "; counter-increment: item }

生成器函数返回符合iterator protocol的对象,并且可以使用this将迭代器的输出委托给另一个可迭代对象(如数组)。

yield*