我正在做一个带有默认选项对象的小型JavaScript模块,它看起来像这样:

 var myModule = function() {

  // Define option defaults
  var defaults = {
    foo: 'bar',
    fooObject: {
      option1: [],
      option2:true,
      option3: false,
    }
  }

  // Create options by extending defaults with the passed in arugments
  if (arguments[0] && typeof arguments[0] === "object") {
    this.options = extendDefaults(defaults, arguments[0]);
  }
}

所以当我这样调用我的模块时
var moduleInstance = new myModule({
  foo: 'some value',
  fooObject: {
    option1: [1, 2, 3]
  }
});
moduleInstance.options.foo; //will retrurn an array [1, 2, 3]

moduleInstance.options.fooObject; //will only contain option1

我理解为什么在创建对象时未定义option2和option3的原因,但是我无法解决该问题。
我在其他框架上使用jQuery的所有代码片段。

编辑:

很抱歉,extendDefault()在这里丢失了:
    function extendDefaults(source, properties) {
  var property;
  for (property in properties) {
    if (properties.hasOwnProperty(property)) {
      source[property] = properties[property];
    }
  }
  return source;
}

编辑:可以解决

我最终这样做了
http://jsfiddle.net/optionsit/sgmme5dy/

在检查hasOwnProperty的循环中

我把那个if语句if(typeof properties[property] === 'object' && typeof properties[property].nodeType === 'undefined' )
因此我可以检查该值是否是对象,而不是DOM元素(因为我也在顶级值中传递了一些DOM元素)

如果它是一个JavaScript对象,那么我将遍历它的子项,以查看是否在参数中设置了它们,并仅在它们被替换时才替换它们。

它可能不是很漂亮,但是适用于我的用例,如果您有更好的选择,请随时发表评论,我将接受更漂亮的答案。

谢谢你的帮助

最佳答案

您只需要递归调用extendDefaults:

function extendDefaults(source, properties) {
    var property;

    for (property in properties) {
        if (properties.hasOwnProperty(property)) {
            if (typeof properties[property] === 'object' && typeof properties[property].nodeType === 'undefined') {
                extendDefaults(source[property], properties[property]);
            } else {
                source[property] = properties[property];
            }
        }
    }

    return source;
}

这是更新的小提琴:http://jsfiddle.net/sgmme5dy/3/

请记住,此函数将破坏null值和Date属性,因为:typeof null === 'object'typeof new Date === 'object'

要处理这些,只需将其添加到if中:
if (typeof properties[property] === 'object' && properties[property] !== null && !(properties[property] instanceof Date) && typeof properties[property].nodeType === 'undefined')

编辑:完全忘记了数组,它们也是typeof object。最后,我认为最好仅依靠那里现有的许多extend函数之一。例如,如果您使用jQuery,则可以使用$.extend;或者,如果您使用lodash / underscorejs,则可以使用_.assign。如果您不使用或不想使用这些库中的任何一个,那么也有一些小型独立库,例如:node-deep-extend

关于javascript - javascript模块扩展嵌套对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31937790/

10-09 05:40
查看更多