Распространение итерируемого ... obj [Symbol.iterator] (...) - PullRequest
2 голосов
/ 19 июня 2020

Я понимаю большую часть следующего кода, но я полностью застрял на [...numbers[Symbol.iterator].

var numbers = {
    *[Symbol.iterator]({
        start = 0,
        stop = 100,
        step = 1
    } = {}) {
        for(let x = start; x <= stop; x+=step) {
            yield x;
        }
    }
};

// should print 0.. 100 in steps of 1
for(let num of numbers) {
    console.log(num);
}

// should print 6..30 in steps of 4
console.log(`My lucky numbers are: ${
    [...numbers[Symbol.iterator]({
        start: 6,
        stop: 30,
        step: 4
    })]}`
);

На мой взгляд:

Если бы это было просто [...numbers], это было бы распределите числа от 0 до 100, потому что объект имеет функцию / генератор итератора. Если бы это было просто numbers[Symbol.iterator](), он бы поискал и вернул генератор.

Но я понятия не имею о [...numbers[Symbol.iterator](...), которое выглядит как странная комбинация этих двух.

I Я изо всех сил пытаюсь получить результаты при поиске в Google этого синтаксиса. Если бы кто-нибудь мог объяснить это, как будто мне 5 лет, я был бы очень признателен!

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Это действительно странное использование Symbol.iterator, обычно вы не должны указывать им параметры. Вы можете разделить его на

const generatorFunction = numbers[Symbol.iterator];
const iterator = generatorFunction({
    start: 6,
    stop: 30,
    step: 4
});
const array = [...iterator];
console.log(`My lucky numbers are: ${array}`);

. Обратите внимание, что iterator является итеративным, он наследует метод [Symbol.iterator], возвращающий сам себя, что позволяет использовать его в элементе распространения массива. То, что метод генератора (который здесь вызывается явно) также имеет имя [Symbol.iterator], не имеет значения, это только приводит к путанице. Лучше написать это в стиле

const numbers = {
    *range(start, stop, step=1) {
        for(let x = start; x <= stop; x+=step) {
            yield x;
        }
    },
    [Symbol.iterator]() {
        return this.range(0, 100);
    },
};

console.log([...numbers.range(6, 30, 4)]);
0 голосов
/ 19 июня 2020

Первоначально я не понял первую половину ответа Берги

Это стало ясно (по крайней мере, для моего мозга), если рассматривать как оставление оператора спреда до последнего, что, честно говоря, это именно то, что он объяснил , но я не мог его увидеть.

В любом случае:

[numbers[Symbol.iterator]({...})] возвращает генератор, который равен , затем спред.

...