Почему получение преобразованного объекта в генераторе JavaScript приводит к другому поведению при преобразовании в массив? - PullRequest
1 голос
/ 28 сентября 2019

У меня есть функция генератора foo, написанная на JavaScript.

function* foo() {
    const bar = { a: 0, b: 0 };
    yield bar;

    bar.a += 1;
    yield bar;

    bar.b += 10;
    yield bar;
}

Функция foo не принимает параметров, но сохраняет внутренний объект bar, который используется для выдачи.Функция может выдавать 3 раза, каждый раз возвращая различное значение.

Ожидаемое поведение наблюдается при вызове next().value для результирующего объекта.

const baz = foo()
console.log(baz.next().value)   // => { a: 0, b: 0 }
console.log(baz.next().value)   // => { a: 1, b: 0 }
console.log(baz.next().value)   // => { a: 1, b: 10 } 

Однако при использовании Array.from метод для создания массива из полученного итератора, вместо этого наблюдается странное поведение.

console.log(Array.from(foo()))  // => [ { a: 1, b: 10 }, { a: 1, b: 10 }, { a: 1, b: 10 } ]

Конечный объект возвращается для каждого выхода вместо того, чтобы возвращать значение каждый раз, когда вызывается yield!Такое поведение происходит как в узле 10.13, так и в узле 12.7.Почему это происходит?Разве результаты не должны быть одинаковыми для обоих случаев?

1 Ответ

3 голосов
/ 28 сентября 2019

Поскольку в javascript объекты передаются по ссылке, вы модифицируете один и тот же объект после каждого выхода, и в конце вы получаете массив с 3 ссылками на один и тот же объект в памяти в его окончательном состоянии.

Чтобы получитьмассив с различными объектами, вам нужно будет создавать новые объекты на каждом выходе, например, используя синтаксис распространения объекта.

function* foo() {
    let bar = { a: 0, b: 0 };
    yield bar;

    bar = {...bar, a: bar.a + 1}
    yield bar;
    
    bar = {...bar, b: bar.b + 10}
    yield bar;
}

const baz = foo()
console.log([...baz])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...