Как дублировать свойства объекта в другом объекте?

С учетом объекта:

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?

Ответ 1

for(var k in firstObject) secondObject[k]=firstObject[k];

Ответ 2

Взяв сигнал от @Bardzuśny, ответьте здесь, ES6 предоставил собственное решение: Object.assign() функция!

Использование прост:

Object.assign(secondObject, firstObject);

Что это!

Поддержка прямо сейчас явно безнадежна; только Firefox (34+) поддерживает его по-настоящему, в то время как Chrome (45+) и Opera (32+) требуют установки "экспериментального флага".

Поддержка улучшается, поддерживая ее самые последние версии Chrome, Firefox, Opera, Safari и Edge (у IE особенно нет поддержки.) Также доступны Transpilers, такие как Babel и Traceur. Подробнее см. здесь.

Ответ 3

Прокрутите свойства первого объекта и назначьте их второму объекту, например:

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 для подробного объяснения причин.

Ответ 4

Согласно ES6 - распространяемый синтаксис:

Вы можете просто использовать:

const thirdObject = {
   ...firstObject,
   ...secondObject   
}

Это позволяет избежать проблем с передачей этих объектов по ссылке.

Кроме того, он заботится об объектах, которые имеют глубокое вложение.

Ответ 5

Играя в некромант, потому что 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 (включая эти два).

(Я все для полифилов, а не для того, чтобы сдерживать использование новых, новых функций языка.)

Ответ 6

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;
};

Ответ 7

Можно использовать 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)

Ответ 8

Это должно работать, протестировано здесь.

var secondObject = {
    firstObject: JSON.parse(JSON.stringify(firstObject)),
    key3 : 'value3',
    key4 : 'value4'
};

Примечание: это не будет копировать методы firstObject
Примечание 2: для использования в старых браузерах вам понадобится json parser
Примечание 3: назначение по ссылке является жизнеспособным вариантом, особенно если firstObject содержит методы. Соответственно отредактировал данный пример jsfiddle

Ответ 9

К сожалению, вы не можете поместить ссылку на переменную в подобном объекте. Однако вы можете создать функцию, которая копирует значения объекта в другой объект.

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 );

Ответ 10

Если вы хотите захватить только свойства, существующие во втором объекте, вы можете использовать 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;
}, {});

Ответ 11

Улучшение идеи 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);

Ответ 12

Я предпочел бы использовать 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 +

Ответ 13

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, но нашел, что это работает. Я думаю, это слишком долго, но это работает.