首页 > 解决方案 > 在 JavaScript ES6 中,调用 iterable[Symbol.iterator] 时将 `this` 绑定到 iterable,但 Mozilla 和 ES6 规范都没有提到它?

问题描述

目前,Mozilla 规范ES6 规范都提到了 iterableobj的含义如下:

obj[Symbol.iterator]应该引用一个零参数函数,这样当被调用时,应该返回一个符合迭代器协议的对象

但是他们都没有提到这个函数实际上是在obj自身上调用的。

这可能很重要,因为我刚刚看到了这样的用法:

const aClass = {
  teacher: "Mary",
  students: ["Peter", "Michael"],
  location: "Room 123, Building One",
  
  [Symbol.iterator]: function* () {
    yield this.teacher;
    for (const student of this.students) {
      yield student;
    }
  }
};

for (const member of aClass) console.log(member);

console.log([...aClass]);

请注意,老师和两个学生都被打印出来了。

所以这个[Symbol.iterator]协议就像:给这个对象的用户一种迭代我的方式,以我指定的方式。

所以 Mozilla 和 ES6 的规范真的应该提到这个函数是在可迭代对象上调用的,还是this绑定到可迭代对象?

(或者也许 ES6 实现规范提到了它......但我认为接口应该告诉所有关于它是如何使用的,并且不应该要求用户也阅读实现)。

标签: javascriptecmascript-6iterable

解决方案


您可以以编程方式使用您想要.call[Symbol.iterator]任何值:this

const aClass = {
  teacher: "Mary",
  students: ["Peter", "Michael"],
  location: "Room 123, Building One",
  
  [Symbol.iterator]: function* () {
    yield this.teacher;
    for (const student of this.students) {
      yield student;
    }
  }
};

const iterator = aClass[Symbol.iterator].call({ foo: null });
console.log(iterator.next());
console.log(iterator.next());

但是对于这种情况,您通过调用迭代器

console.log([...aClass]);

它执行(除其他外)ArrayAccumulation中描述的步骤:

SpreadElement : ... AssignmentExpression

1. Let spreadRef be the result of evaluating AssignmentExpression.
2. Let spreadObj be GetValue(spreadRef).
3. Let iterator be GetIterator(spreadObj).
4. ReturnIfAbrupt(iterator).
5. Repeat (iterate over iterator, assign properties to the array being created)

看看GetIterator

  a. Let method be GetMethod(obj, @@iterator).
  ...
3. Let iterator be Call(method,obj).

第一个参数在哪里obj传递(对于ArrayAccumulation,它是spreadObj)。

Call它使用第二个参数的调用上下文 (a this)调用作为第一个参数传递的函数。

所以[...aClass]调用aClass[Symbol.iterator]的调用上下文为aClass.

循环从Runtime Semantics: ForIn/OfHeadEvaluationfor..of获取迭代器,在这种情况下:

a. Assert: iterationKind is iterate.
b. Return GetIterator(exprValue).

导致与(使用 的调用上下文调用[...aClass]迭代器)相同的事情aClassaClass


推荐阅读