代码之家  ›  专栏  ›  技术社区  ›  Borek Bernard

类似jQuery.extend()但独立的东西?

  •  15
  • Borek Bernard  · 技术社区  · 14 年前

    我正在寻找一种将两个配置对象合并在一起的方法,比如:

    var developmentConfig = {
      url: "localhost",
      port: 80
    };
    
    var productionConfig = {
      url: "example.com"
    };
    
    var config = isDevelopment ? developmentConfig : jQuery.extend(developmentConfig, productionConfig);
    

    然而,这是一个Node.js应用程序,我不想包含jQuery,我正在寻找类似但独立的应用程序。我知道我自己也可以写类似的东西,但我更愿意使用经过测试和验证的东西(当配置对象使用更丰富的层次结构时,会出现边缘情况、复杂情况等)

    编辑 :简单的迭代是不够的,因为它不能处理层次结构。Underscore的也没有 extend

    3 回复  |  直到 14 年前
        1
  •  20
  •   nickf    12 年前

    如果你所需要的只是扩展,那么用几行代码写出来就很简单了。如果你想要递归扩展,如果你想要有圆形结构、具有复杂原型链的对象等,那么完全通用地实现这一点是很困难的。如果它只是一些嵌套的普通对象,那么这应该有效:

    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没有提供的其他类似函数,请查看 Underscore 其也可通过NPM用于节点。

        2
  •  5
  •   Maxim Ponomarev    13 年前

    在这个问题上,为未来的朝圣者提供了一个简单的独立功能的又一个例子,保护他们免受不同类型财产的合并:

    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 } }
    
        3
  •  3
  •   user3666197    11 年前

    此解决方案创建 新对象 并且能够处理 多个对象

    此外,它是 递归的 你可以选择天气 希望 覆盖值 对象

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

    新扩展对象的内容:

    {"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/