Ответ 1
for(var k in firstObject) secondObject[k]=firstObject[k];
С учетом объекта:
var firstObject = {
key1 : 'value1',
key2 : 'value2'
};
как я могу скопировать свойства внутри другого объекта (secondObject
) следующим образом:
var secondObject = {
key1 : 'value1',
key2 : 'value2',
key3 : 'value3',
key4 : 'value4'
};
используя ссылку на firstObject
? Что-то вроде этого:
var secondObject = {
firstObject,
key3 : 'value3',
key4 : 'value4'
};
(это не работает... Я поставил его просто для того, чтобы показать в больших строках, как я хотел бы структурировать код).
Возможно ли решение без с использованием каких-либо фреймворков JavaScript?
for(var k in firstObject) secondObject[k]=firstObject[k];
Взяв сигнал от @Bardzuśny, ответьте здесь, ES6 предоставил собственное решение: Object.assign()
функция!
Использование прост:
Object.assign(secondObject, firstObject);
Что это!
Поддержка прямо сейчас явно безнадежна; только Firefox (34+) поддерживает его по-настоящему, в то время как Chrome (45+) и Opera (32+) требуют установки "экспериментального флага".
Поддержка улучшается, поддерживая ее самые последние версии Chrome, Firefox, Opera, Safari и Edge (у IE особенно нет поддержки.) Также доступны Transpilers, такие как Babel и Traceur. Подробнее см. здесь.
Прокрутите свойства первого объекта и назначьте их второму объекту, например:
var firstObject = {
key1 : 'value1',
key2 : 'value2'
};
var secondObject = {
key3 : 'value3',
key4 : 'value4'
};
for (var prop in firstObject) {
if (firstObject.hasOwnProperty(prop)) {
secondObject[prop] = firstObject[prop];
}
}
Цикл for
- in
недостаточно; вам нужно hasOwnProperty
. См. http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop для подробного объяснения причин.
Согласно ES6 - распространяемый синтаксис:
Вы можете просто использовать:
const thirdObject = {
...firstObject,
...secondObject
}
Это позволяет избежать проблем с передачей этих объектов по ссылке.
Кроме того, он заботится об объектах, которые имеют глубокое вложение.
Играя в некромант, потому что ES5 принес нам Object.keys()
, что может спасти нас от всех этих проверок .hasOwnProperty()
.
Object.keys(firstObject).forEach(function(key) {
secondObject[key] = firstObject[key];
});
Или, обернув его в функцию (ограниченная "копия" lodash _.assign()
):
function assign(object, source) {
Object.keys(source).forEach(function(key) {
object[key] = source[key];
});
}
assign(secondObject, firstObject); // assign firstObject properties to secondObject
Object.keys()
- относительно новый метод, наиболее заметно: недоступен в IE < 9. То же самое происходит для метода массива .forEach()
, который я использовал вместо регулярного цикла for
.
К счастью, для этих древних браузеров существует es5-shim, который будет polyfill многими функциями ES5 (включая эти два).
(Я все для полифилов, а не для того, чтобы сдерживать использование новых, новых функций языка.)
Necro'ing, чтобы люди могли найти метод глубокой копии с hasOwnProperty и фактическую проверку объекта:
var extend = function (original, context, key) {
for (key in context)
if (context.hasOwnProperty(key))
if (Object.prototype.toString.call(context[key]) === '[object Object]')
original[key] = extend(original[key] || {}, context[key]);
else
original[key] = context[key];
return original;
};
Можно использовать Object.assign для объединения объектов. Он объединяет и переопределяет общее свойство справа налево, т.е. то же свойство слева будет переопределено справа.
И важно предоставить пустой объект первым, чтобы избежать мутации исходных объектов. Исходные объекты следует оставить чистыми, так как Object.assign()
сам по себе возвращает новый объект.
Надеюсь это поможет!
var firstObject = {
key1 : 'value1',
key2 : 'value2'
};
var secondObject = {
key3 : 'value3',
key4 : 'value4'
};
var finalObject = Object.assign({}, firstObject, secondObject)
console.log(finalObject)
Это должно работать, протестировано здесь.
var secondObject = {
firstObject: JSON.parse(JSON.stringify(firstObject)),
key3 : 'value3',
key4 : 'value4'
};
Примечание: это не будет копировать методы firstObject
Примечание 2: для использования в старых браузерах вам понадобится json parser
Примечание 3: назначение по ссылке является жизнеспособным вариантом, особенно если firstObject
содержит методы. Соответственно отредактировал данный пример jsfiddle
К сожалению, вы не можете поместить ссылку на переменную в подобном объекте. Однако вы можете создать функцию, которая копирует значения объекта в другой объект.
function extend( obj1, obj2 ) {
for ( var i in obj2 ) {
obj1[i] = obj2[i];
}
return obj1;
}
var firstObject = {
key1: "value1",
key2: "value2"
};
var secondObject = extend({
key3: "value3",
key4: "value4"
}, firstObject );
Если вы хотите захватить только свойства, существующие во втором объекте, вы можете использовать Object.keys
для захвата свойств первого объекта, вы можете сделать два метода:
A.) map
, чтобы назначить первые свойства объекта второму объекту с использованием побочных эффектов:
var a = {a:100, b:9000, c:300};
var b = {b:-1};
Object.keys(a).map(function(key, index) {
if (typeof b[key] !== 'undefined') {
console.log(key);
b[key] = a[key];
}
});
B.) или reduce
, чтобы создать новый объект и назначить его второму объекту. Имейте в виду, что этот метод заменяет другие свойства, которые может иметь второй объект до того, который не соответствует первому объекту:
var a = {a:100, b:9000, c:300};
var b = {b:-1, d:-1}; // d will be gone
b = Object.keys(a).reduce(function(result, current) {
if (typeof b[current] !== 'undefined') {
result[current] = a[current];
}
return result;
}, {});
Улучшение идеи kingPuppy и идеи OP (мелкая копия) - я добавляю только 3 точки к "примеру" OP :)
var secondObject = {
...firstObject,
key3 : 'value3',
key4 : 'value4'
};
var firstObject = {
key1 : 'value1',
key2 : 'value2'
};
var secondObject = {
...firstObject,
key3 : 'value3',
key4 : 'value4'
};
console.log(secondObject);
Я предпочел бы использовать firstObject в качестве прототипа secondObject и добавить дескриптор свойства:
var secondObject = Object.create(firstObject, {
key3: {value: "value3", writable: true, configurable: true, enumerable: true},
key4: {value: "value4", writable: true, configurable: true, enumerable: true}
});
Это, конечно, не однострочный, но он дает вам больше контроля. Если вас интересуют дескрипторы свойств, я предлагаю прочитать эту статью: http://patrickdelancy.com/2012/09/property-descriptors-in-javascript/#comment-2062 и MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Вы также можете просто назначить значения и опустить дескрипторы и сделать их немного короче:
var secondObject = Object.create(firstObject, {
key3: {value: "value3"}
key4: {value: "value4"}
});
Совместимость: ECMAScript 5, поэтому IE9 +
var firstObject = {
key1: "value1",
key2: "value2"
};
var secondObject = {
key3: "value3",
key4: "value4"
copy: function(firstObject){
this.key1 = firstObject.key1;
this.key2 = firstObject.key2;
}
};
Использование следующего метода скопирует свойства
secondObject.copy(firstObject)
Я очень новичок в JavaScript, но нашел, что это работает. Я думаю, это слишком долго, но это работает.