Почему конструкторы методов генератора?
Методы, объявленные как методы (с использованием расширенных объектных литератур или классов 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, заключается в том, что генераторные методы не должны быть конструкторами.