web-dev-qa-db-ja.com

ES6 +で2つのjavascriptオブジェクトをマージするにはどうすればよいですか?

私はいつもこのようなコードを書かなければならないことにうんざりしています:

function shallowExtend(obj1,obj2){
  var key;
  for ( key in obj2 ) {
    if ( obj2.hasOwnProperty(key) === false )  continue;
    obj1[key] = obj2[key]
  }
}

または、自分でコードを書きたくない場合は、既にそれを行うライブラリを実装します。 ES6 +は、Object.prototype.extend(obj2...)Object.extend(obj1,obj2...)のようなものを提供してくれるでしょう。

ES6 +はそのような機能を提供しますか?まだない場合、そのような機能は計画されていますか?計画されていない場合、なぜそうではないのですか?

132
balupton

Object.assignを使用して、ES6で浅いマージ/拡張/割り当てを行うことができます。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

構文:

Object.assign(targetsources);

ここで、... sourcesはソースオブジェクトを表します。

例:

var obj1 = {name: 'Daisy', age: 30};
var obj2 = {name: 'Casey'};

Object.assign(obj1, obj2);

console.log(obj1.name === 'Casey' && obj1.age === 30);
// true
197
Jack

これには object spread syntax を使用できます:

const merged = {...obj1, ...obj2}

配列の場合、スプレッド演算子はすでにES6(ES2015)の一部でしたが、オブジェクトの場合はES9(ES2018)の言語仕様に追加されました。その提案は、バベルのようなツールでそれよりずっと前にデフォルトで有効にされていました。

143

私はこれが少し古い問題であることを知っていますが、ES2015/ES6で最も簡単な解決策は、Object.assign()を使用して、実際には非常に簡単です。

これが役立つことを願っていますDEEPマージも:

/**
 * Simple is object check.
 * @param item
 * @returns {boolean}
 */
export function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);
}

/**
 * Deep merge two objects.
 * @param target
 * @param source
 */
export function mergeDeep(target, source) {
  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }
  return target;
}

使用例:

mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }
11
Salakar

Object.mixinの追加は、あなたが求めている振る舞いを処理するために現在議論されています。 https://mail.mozilla.org/pipermail/es-discuss/2012-December/027037.html

ES6ドラフトにはまだ含まれていませんが、多くのサポートがあるように思われるので、すぐにドラフトに登場すると思います。

7
Nathan Wall

ES6

Object.assign(o1,o2) ; 
Object.assign({},o1,o2) ; //safe inheritance
var copy=Object.assign({},o1); // clone o1
//------Transform array of objects to one object---
var subjects_assess=[{maths:92},{phy:75},{sport:99}];
Object.assign(...subjects_assess); // {maths:92,phy:75,sport:99}

ES7またはBabel

{...o1,...o2} // inheritance
 var copy= {...o1};
6
Abdennour TOUMI

おそらくES5 Object.defineProperties メソッドが仕事をするでしょうか?

例えば.

var a = {name:'fred'};
var b = {age: {value: 37, writeable: true}};

Object.defineProperties(a, b);

alert(a.age); // 37

MDNドキュメント: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperties

5
RobG