Задать вопрос
@ivandao

Как присвоить объект по значению, а не по ссылке?

Как присвоить объект по значению, а не по ссылке?

Думал сделать так, но это как-то некрасиво
newObj =  JSON.parse( JSON.stringify( sourceObj ) )
  • Вопрос задан
  • 262 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 3
lavezzi1
@lavezzi1
Если правильно понял
// ES5
const newObj = Object.assign({}, sourceObj);

// ES6
const newObj = { ...sourceObj };
Ответ написан
It depends
Если все свойства твоего объекта - простые, то const newObj = { ...sourceObj };
Если свойства объекта могут быть объектами и тебе нужно их тоже скопировать, то нужно копировать рекурсивно
можешь подсмотреть тут
https://github.com/mateusmaso/underscore.deepclone...
Ответ написан
Комментировать
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Вам определенно нужен deepClone
Можно взять готовый например из lodash, но я бы предложил Вам свою реализацию.
Пока писал ее в ответ, понял, что в очередной раз мой ответ превращается в целую статью, поэтому разместил ее на хабре: https://habr.com/ru/post/466535/

Ну или можете просто скопировать код и использовать:
function deepClone(source) {
	return ({
		'object': cloneObject,
		'function': cloneFunction
	}[typeof source] || clonePrimitive)(source)();
}

function cloneObject(source) {
	return (Array.isArray(source)
		? () => source.map(deepClone)
		: clonePrototype(source, cloneFields(source, simpleFunctor({})))
	);
}

function cloneFunction(source) {
	return cloneFields(source, simpleFunctor(function() {
		return source.apply(this, arguments);
	}));
}

function clonePrimitive(source) {
	return () => source;
}

function simpleFunctor(value) {
	return mapper => mapper ? simpleFunctor(mapper(value)) : value;
}

function makeCloneFieldReducer(source) {
	return (destinationFunctor, field) => {
		const descriptor = Object.getOwnPropertyDescriptor(source, field);
		return destinationFunctor(destination => Object.defineProperty(destination, field, 'value' in descriptor ? {
			...descriptor,
			value: deepClone(descriptor.value)
		} : descriptor));
	};
}

function cloneFields(source, destinationFunctor) {
	return (Object.getOwnPropertyNames(source)
		.concat(Object.getOwnPropertySymbols(source))
		.reduce(makeCloneFieldReducer(source), destinationFunctor)
	);
}

function clonePrototype(source, destinationFunctor) {
	return destinationFunctor(destination => Object.setPrototypeOf(destination, Object.getPrototypeOf(source)));
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы