15

次のような 2 つの構成オブジェクトをマージする方法を探しています。

var developmentConfig = {
  url: "localhost",
  port: 80
};

var productionConfig = {
  url: "example.com"
};

var config = isDevelopment ? developmentConfig : jQuery.extend(developmentConfig, productionConfig);

ただし、これは Node.js アプリであり、jQuery を含めたくないので、似ているがスタンドアロンのものを探しています。私は自分で似たようなものを書くことができることを知っていますが、テストされ証明されたものを使用したいと思います (エッジケース、構成オブジェクトがより豊富な階層を使用する場合の複雑さなどがあります)。

編集:階層構造を処理しないため、単純な反復では不十分です。Underscore のextend.

4

3 に答える 3

20

拡張だけが必要な場合は、数行で簡単に記述できます。再帰的な拡張が必要な​​場合、循環構造、複雑なプロトタイプチェーンを持つオブジェクトなどが必要な場合は、完全に一般的に行うのは難しいです.ネストされた単純なオブジェクトの場合、これはうまくいくはずです:

function extend (target, source) {
  target = target || {};
  for (var prop in source) {
    if (typeof source[prop] === 'object') {
      target[prop] = extend(target[prop], source[prop]);
    } else {
      target[prop] = source[prop];
    }
  }
  return target;
}

これを実行する軽量ライブラリ (上記の理由により再帰を除く) および javascript によって提供されない他の同様の関数を探している場合は、NPM 経由でノードでも利用できるUnderscoreを参照してください。

于 2012-09-07T11:17:13.843 に答える
5

異なるタイプのプロパティのマージからの保護を備えた、この質問に対する将来の巡礼者のための単純なスタンドアロン関数のもう 1 つの例:

function extend(obj) {
    Array.prototype.slice.call(arguments, 1).forEach(function(source) {
        if (source) {
            for (var prop in source) {
                if (source[prop].constructor === Object) {
                    if (!obj[prop] || obj[prop].constructor === Object) {
                        obj[prop] = obj[prop] || {};
                        extend(obj[prop], source[prop]);
                    } else {
                        obj[prop] = source[prop];
                    }
                } else {
                    obj[prop] = source[prop];
                }
            }
        }
    });
    return obj;
}

使用法:

extend({ name:'Maria', address:{ city:'Moscow', street:'Lenina str, 52' } }, { name:'Marianna', address:{ zip:1200003 }})
=> { name:'Marianna', address:{ city:'Moscow', street:'Lenina str, 52', zip:1200003 } }
于 2013-01-30T13:08:36.310 に答える
3

このソリューションは、新しいオブジェクトを作成し、複数のオブジェクトを処理できます。

さらに、再帰的で、値とオブジェクト上書きする天気を選択できます

    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/

于 2014-10-13T21:07:35.807 に答える