Почему конструкторы методов генератора?

Методы, объявленные как методы (с использованием расширенных объектных литератур или классов ES6), не являются конструкторами/не имеют цепочку прототипов.

Но генераторы, объявленные с помощью синтаксиса метода, имеют цепочку прототипов и являются конструкторами.

Возьмем следующий пример - (требуется v8)

'use strict';
class x {
  *a() { this.b() }
  b() { print('class method'); }
}
let i = new x();
i.a.prototype.b = function() { print('generator method'); };
i.a().next();
(new i.a()).next();

Выходы,

class method
generator method

При добавлении прототипов к i.b, а вызов new i.b() приведет к ошибке, потому что i.b не является конструктором, Я могу сделать new i.a(), а this внутри *a получает другой контекст.

  • Почему существует эта разница?
  • Каков прецедент для прототипа в генераторах, определенных как методы?

Ответ 1

Определенно странная причуда спецификации ES2015. TC39 на самом деле долго обсуждал в июле и решил сделать генераторы не -. new возможность

Официальное изменение спецификации приземлилось в прошлом месяце, и хотя была небольшая озабоченность по поводу нарушения, разработчики V8 и SpiderMonkey высказались в пользу в будущем, поэтому я ожидаю, что он скоро перестанет работать (и на самом деле он уже выбрал TypeError в Firefox Nightly).

Ответ 2

Я думаю, это сводится к тому, что метод генератора ES6 возвращает объект, который включает итератор и итеративные протоколы, которые позволяют генераторам работать из коробки с языковыми функциями, которые могут выполнять итерацию по коллекциям (например, для... )

Из документации MDN на https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator:

Чтобы быть итерабельным, объект должен реализовать метод @@iterator, что означает, что объект (или один из объектов в цепочке прототипов) должен иметь свойство с ключом Symbol.iterator.

И хороший момент, поднятый @bergi, заключается в том, что генераторные методы не должны быть конструкторами.