JavaScript генераторов и их прототипные цепочки - PullRequest
6 голосов
/ 07 августа 2020

Я играю с генераторами JavaScript и у меня есть 2 вопроса, основанных на следующем коде и его выводе:

const a = function*(){}(); // Object [Generator] {}
const b = a.__proto__;     // Object [Generator] {}
const c = b.__proto__;     // Object [Generator] {}
const d = c.__proto__;     // {}
const e = d.__proto__;     // {}
const f = e.__proto__;     // null
console.log(a, b, c, d, e, f);

Вопрос 1

Кажется, каждый объект генератора имеет свои собственный уникальный прототип, и все они имеют общий прототип:

const x = function*(){}();
const y = x.__proto__;
const z = y.__proto__;
console.log(b === y); // false
console.log(c === z); // true

Правильно ли мое понимание выше?

Вопрос 2

Поскольку f это null, e вероятно Object.prototype:

console.log(e === Object.prototype); // true

Однако я не могу понять, что такое d. Есть ли Something.prototype, равное d?

Ответы [ 2 ]

2 голосов
/ 07 августа 2020

Да. Давайте разберем это еще немного:

function* g() {} // a generator function
const GeneratorFunction = Object.getPrototypeOf(g).constructor;
console.assert(Object.getPrototypeOf(GeneratorFunction) == Function);
const Generator = GeneratorFunction.prototype;
console.assert(Object.getPrototypeOf(Generator) == Function.prototype);
const ArrayIteratorPrototype = Object.getPrototypeOf([].values());

const a = g(); // a generator
console.assert(a instanceof g);

const b = Object.getPrototypeOf(a); // a prototype object
console.assert(b == g.prototype);

const c = Object.getPrototypeOf(b); // the Generator.prototype
console.assert(c == Generator.prototype);

const d = Object.getPrototypeOf(c); // the Iterator.prototype
console.assert(d == Object.getPrototypeOf(ArrayIteratorPrototype));

const e = Object.getPrototypeOf(d); // the Object.prototype
console.assert(e == Object.prototype);

const f = Object.getPrototypeOf(e); // null
console.assert(f == null);

Объект d, который вы искали, является объектом-прототипом, общим для всех итераторов (итераторы массива, итераторы карты, итераторы набора, итераторы строк и т. Д. c), в том числе генераторы. Нет глобального Iterator ( еще ), так же как нет глобальных Generator или GeneratorFunction.

2 голосов
/ 07 августа 2020

В разделе GeneratorFunction Objects есть фигура отношений: generator_objects_relationships

Question 1

Yes.

Question 2

d is an IteratorPrototype . И с помощью do c:

Следующее выражение является одним из способов, которым код ECMAScript может получить доступ к объекту% IteratorPrototype%:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

Кажется, что там не Iterator, так что Iterator.prototype равно d.

...