У меня (ошибочно) сложилось впечатление, что оператор сканирования всегда будет возвращать новый объект при каждом проходе.Недавно я обнаружил, что это не так.
Я разобрал пример из learnrxjs.io , чтобы продемонстрировать, что я имею в виду здесь .
Взглянув на код:
const subject = new Rx.Subject();
const example = subject.scan((acc, curr) => {
console.log('Accumulator', acc);
return Object.assign({}, acc, curr)
}, {});
//log accumulated values
const subscribe = example.subscribe(val => {
val.mutating = 'test'
console.log('Accumulated object:', val)
});
//next values into subject, adding properties to object
subject.next({name: 'Joe'});
// {name: 'Joe'}
subject.next({age: 30});
// {name: 'Joe', age: 30}
subject.next({favoriteLanguage: 'JavaScript'});
// {name: 'Joe', age: 30, favoriteLanguage: 'JavaScript'}
Я изменяю val
, передаваемый по потоку в subscription
, и выхожу из значения accumulator
вscan
функция аккумулятора.
Глядя на консоль, видно, что аккумулятор содержит mutating:"test"
после первого и последующих проходов:
![enter image description here](https://i.stack.imgur.com/DK04k.png)
Если я не ошибаюсь, это демонстрирует, что я могу изменять потоковые объекты в любом месте по линии вверх и до подписки.Что, я полагаю, не удивляет меня, поскольку это ссылка на объект.Но я подумал, что оператор scan
всегда будет возвращать новый объект, предотвращающий мутацию его внутреннего аккумулятора ...
Сначала я подумал о том, чтобы отобразить новый объект, подобный этому:
scan((acc, curr) => Object.assign({}, acc, curr), {}),
map(data=>Object.assign({}, data))
Но мне это кажется странным.
Является ли поведение, которое я демонстрирую, ожидаемым или я не понимаю, как все это работает?Как я могу предотвратить мутацию аккумулятора?
Спасибо