Как динамически объединить свойства двух объектов JavaScript? - PullRequest
2173 голосов
/ 05 октября 2008

Мне нужно иметь возможность объединять два (очень простых) объекта JavaScript во время выполнения. Например, я хотел бы:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

Кто-нибудь имеет сценарий для этого или знает встроенный способ сделать это? Мне не нужна рекурсия, и мне не нужно объединять функции, только методы для плоских объектов.

Ответы [ 60 ]

0 голосов
/ 04 декабря 2013

Я использовал Object.create (), чтобы сохранить настройки по умолчанию (используя __proto__ или Object.getPrototypeOf ()).

function myPlugin( settings ){
    var defaults = {
        "keyName": [ "string 1", "string 2" ]
    }
    var options = Object.create( defaults );
    for (var key in settings) { options[key] = settings[key]; }
}
myPlugin( { "keyName": ["string 3", "string 4" ] } );

Таким образом, я всегда могу использовать 'concat ()' или 'push ()' позже.

var newArray = options['keyName'].concat( options.__proto__['keyName'] );

Примечание : вам потребуется выполнить проверку hasOwnProperty перед объединением, чтобы избежать дублирования.

0 голосов
/ 02 июня 2012
function extend()
{ 
    var o = {}; 

    for (var i in arguments)
    { 
        var s = arguments[i]; 

        for (var i in s)
        { 
            o[i] = s[i]; 
        } 
    } 

    return o;
}
0 голосов
/ 31 марта 2015

Другой метод:

function concat_collection(obj1, obj2) {
    var i;
    var arr = new Array();

    var len1 = obj1.length;
    for (i=0; i<len1; i++) {
        arr.push(obj1[i]);
    }

    var len2 = obj2.length;
    for (i=0; i<len2; i++) {
        arr.push(obj2[i]);
    }

    return arr;
}

var ELEMENTS = concat_collection(A,B);
for(var i = 0; i < ELEMENTS.length; i++) {
    alert(ELEMENTS[i].value);
}
0 голосов
/ 26 сентября 2015

Если вы используете Dojo Toolkit , тогда лучший способ объединить два объекта - использовать миксин.

Ниже приведен пример для миксина Dojo Toolkit:

// Dojo 1.7+ (AMD)
require(["dojo/_base/lang"], function(lang){
  var a = { b:"c", d:"e" };
  lang.mixin(a, { d:"f", g:"h" });
  console.log(a); // b:c, d:f, g:h
});

// Dojo < 1.7
var a = { b:"c", d:"e" };
dojo.mixin(a, { d:"f", g:"h" });
console.log(a); // b:c, d:f, g:h

Для более подробной информации, пожалуйста, mixin .

0 голосов
/ 31 мая 2018

Мы можем создать пустой объект и объединить его с помощью for-loop:

var obj1 = {
  id: '1',
  name: 'name'
}

var obj2 = {
  c: 'c',
  d: 'd'
}

var obj3 = {}

for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }


console.log( obj1, obj2, obj3)
0 голосов
/ 14 октября 2014

Это решение создает новый объект и может обрабатывать несколько объектов .

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

    function extendObjects() {

        var newObject        = {};
        var overwriteValues  = false;
        var overwriteObjects = false;

        for ( var indexArgument = 0; indexArgument < arguments.length; indexArgument++ ) {

            if ( typeof arguments[indexArgument] !== 'object' ) {

                if ( arguments[indexArgument] == 'overwriteValues_True' ) {

                    overwriteValues = true;            
                } else if ( arguments[indexArgument] == 'overwriteValues_False' ) {

                    overwriteValues = false;                             
                } else if ( arguments[indexArgument] == 'overwriteObjects_True' ) {

                    overwriteObjects = true;     
                } else if ( arguments[indexArgument] == 'overwriteObjects_False' ) {

                    overwriteObjects = false; 
                }

            } else {

                extendObject( arguments[indexArgument], newObject, overwriteValues, overwriteObjects );
            }

        }

        function extendObject( object, extendedObject, overwriteValues, overwriteObjects ) {

            for ( var indexObject in object ) {

                if ( typeof object[indexObject] === 'object' ) {

                    if ( typeof extendedObject[indexObject] === "undefined" || overwriteObjects ) {
                        extendedObject[indexObject] = object[indexObject];
                    }

                    extendObject( object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects );

                } else {

                    if ( typeof extendedObject[indexObject] === "undefined" || overwriteValues ) {
                        extendedObject[indexObject] = object[indexObject];
                    }

                }

            }     

            return extendedObject;

        }

        return newObject;
    }

    var object1           = { a : 1, b : 2, testArr : [888, { innArr : 1 }, 777 ], data : { e : 12, c : { lol : 1 }, rofl : { O : 3 } } };
    var object2           = { a : 6, b : 9, data : { a : 17, b : 18, e : 13, rofl : { O : 99, copter : { mao : 1 } } }, hexa : { tetra : 66 } };
    var object3           = { f : 13, g : 666, a : 333, data : { c : { xD : 45 } }, testArr : [888, { innArr : 3 }, 555 ]  };

    var newExtendedObject = extendObjects( 'overwriteValues_False', 'overwriteObjects_False', object1, object2, object3 );

Содержимое newExtendedObject:

{"a":1,"b":2,"testArr":[888,{"innArr":1},777],"data":{"e":12,"c":{"lol":1,"xD":45},"rofl":{"O":3,"copter":{"mao":1}},"a":17,"b":18},"hexa":{"tetra":66},"f":13,"g":666}

Скрипка: http://jsfiddle.net/o0gb2umb/

0 голосов
/ 07 ноября 2018

С помощью следующего помощника вы можете объединить два объекта в один новый объект:

function extend(obj, src) {
    for (var key in src) {
        if (src.hasOwnProperty(key)) obj[key] = src[key];
    }
    return obj;
}

// example
var a = { foo: true }, b = { bar: false };
var c = extend(a, b);

console.log(c);
// { foo: true, bar: false }

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

Если поддержка IE 8 не требуется, вместо этого вы можете использовать Object.keys для той же функциональности:

function extend(obj, src) {
    Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
    return obj;
}

Это включает немного меньше кода и немного быстрее.

0 голосов
/ 02 февраля 2017

Вы можете сделать следующее в EcmaScript2016

Исправление: это предложение этапа 3, но оно всегда работало для меня

const objA = {
  attrA: 'hello',
  attrB: true
}

const objB = {
  attrC: 2
}

const mergedObj = {...objA, ...objB}
0 голосов
/ 31 декабря 2016

Если вам нужно глубокое слияние, которое также «объединит» массивы путем объединения их в результате, тогда вам может подойти эта функция ES6:

function deepMerge(a, b) {
    // If neither is an object, return one of them:
    if (Object(a) !== a && Object(b) !== b) return b || a;
    // Replace remaining primitive by empty object/array
    if (Object(a) !== a) a = Array.isArray(b) ? [] : {};
    if (Object(b) !== b) b = Array.isArray(a) ? [] : {};
    // Treat arrays differently:
    if (Array.isArray(a) && Array.isArray(b)) {
        // Merging arrays is interpreted as concatenation of their deep clones:
        return [...a.map(v => deepMerge(v)), ...b.map(v => deepMerge(v))];
    } else {
        // Get the keys that exist in either object
        var keys = new Set([...Object.keys(a),...Object.keys(b)]);
        // Recurse and assign to new object
        return Object.assign({}, ...Array.from(keys,
            key => ({ [key]: deepMerge(a[key], b[key]) }) ));
    }
}

// Sample data for demo:
var a = {
    groups: [{
        group: [{
            name: 'John',
            age: 12
        },{
            name: 'Mary',
            age: 20
        }],
        groupName: 'Pair'
    }],
    config: {
        color: 'blue',
        range: 'far'
    }
};


var b = {
    groups: [{
        group: [{
            name: 'Bill',
            age: 15
        }],
        groupName: 'Loner'
    }],
    config: {
        range: 'close',
        strength: 'average'
    }
};

var merged = deepMerge(a, b);

console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Обратите внимание, что если этой функции передается только один аргумент, она действует как функция глубокого клонирования.

0 голосов
/ 19 декабря 2012
A={a:1,b:function(){alert(9)}}
B={a:2,c:3}
A.merge = function(){for(var i in B){A[i]=B[i]}}
A.merge()

Результат: {a: 2, c: 3, b: function ()}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...