javascript - 有没有办法在使用 ES6 速记方法表示法的方法中包含词法 `this` ?

标签 javascript methods ecmascript-6 this bind

关于SO的第一个问题,我希望我没有重复任何内容;我看过other questions并认为我的不同足以值得询问。

基本上,有没有办法让使用速记符号编写的方法的方法主体中的 this 成为词法或绑定(bind)到特定值?

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

请注意,在下面的代码片段中,由于 this 绑定(bind),无法按预期工作,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() 作为常规函数,然后将其绑定(bind)到对象属性赋值中:

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

最佳答案

解决您的问题的理想方法是使用正确的工具来完成工作:a generator function 。它们也可以与 shorthand syntax 一起使用,并且他们将正确绑定(bind) this

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

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

  * [Symbol.iterator]() {
    yield* this.data;
  }
}

const graph = new Graph([1, 2, 3]);
for (const node of graph) {
  console.log(node);
}

关于javascript - 有没有办法在使用 ES6 速记方法表示法的方法中包含词法 `this` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42324619/

相关文章:

ruby-on-rails - 用另一个类的方法包装一个对象

javascript - "Home"不是 Node JS 上的构造函数

javascript - 匿名异步函数调用

javascript - 防止 select2 Dropdown 的 AutoTrigger 事件调用函数

javascript - jQuery/JavaScript : how to remove all elements in the first <li> except <a>text</a>

Java - 将类方法分离到不同的文件中

java - 创建多个子类对象

javascript - 无法设置已编辑的文本

javascript - jQuery - 如何检测剪贴板内容是否已更改?

javascript - 如何定义和访问备用选项名称的数据列表选项