【问题标题】:Combining JavaScript Objects into One将 JavaScript 对象合二为一
【发布时间】:2009-08-26 13:23:12
【问题描述】:

我有一个名为“Colorbox”(jQuery 插件)的函数,它接受许多参数,如下所示:

$(this).colorbox({
    width : "500px",
    height : "500px"
});

不过,我有几种不同类型的“this”,每种都有自己的属性。像这样:

var Type = {
  video: {
    width : "500px",
    height : "500px"
  },
  gallery: {
    width : "1065px",
    height : "600px"
  }
}

除此之外,我还有其他行为、逻辑和一组“默认”设置(被更具体的设置覆盖)。我想要做的是将所有适当的设置从多个对象推送到一个对象中,这样我就可以调用:

$(this).colorbox(Settings);

如何将一组未知的属性及其值(例如“宽度”和“高度”)从 Type.video 之类的内容传输到“设置”?目标是能够调用 Settings.height 并取回我推入的值。

【问题讨论】:

标签: javascript jquery


【解决方案1】:

看看 JQuery extend 方法。它可以将两个对象及其所有属性合并在一起。

来自 JQuery 的示例页面:

var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);

现在设置包含合并的设置和选项对象。

【讨论】:

  • 这看起来很完美!我想我认为会有一个内置的 javascript 方法,但 Extend 似乎完全符合我的需要。谢谢!
  • 这对 OP 来说似乎很有用,但从技术上讲,这不是问题所要求的。 OP 没有提到他想为此使用 jQuery……只是普通的 JavaScript。
  • OP 正在编写一个 jQuery 插件 sp,当在 jQuery 插件中使用 jQuery 函数最有意义时,提供更复杂的解决方案似乎很愚蠢。
【解决方案2】:

JavaScript 有一个简单的原生函数来合并对象。也就是 ES6 中引入的 Object.assign()。

  // creating two JavaScript objects
    var x = { a: true };var y = { b: false}; // merging two objects with JavaScript native function
    var obj = Object.assign(x,y);
    //result
    Console.log(obj); // output is { a: true, b: false }

有关 javascript 合并对象的更多信息,请查看merge JavaScript objects 示例。

【讨论】:

  • 赞成。我不得不升级节点,因为“未定义不是函数”错误 - 即使在运行带有 --harmony 标志的节点时......
  • 这不适用于对象中的嵌套层,它只适用于顶层
  • 为了完整起见:合并的目标是Object.assign的第一个参数,即。示例代码中的x 发生了变异。详情请见here(MDN)
【解决方案3】:

非 jQuery 解决方案是:

YOUROBJ.vars = {
    vars1: {
        vars1_1: 'an object which will overwrite',
        vars1_2: 'an object which will be added'
    }
};

YOUROBJ.vars2 = (!YOUROBJ.vars) ? {} : YOUROBJ.vars;

YOUROBJ.vars = {
    vars1: {
        vars1_1: 'an object which will be overwritten',
        vars1_3: 'an object which will remain'
    }
};

YOUROBJ.extend = function(obj, defaults) {
    for (var i in defaults) {
        if (!obj[i]) {
            obj[i] = defaults[i];
        } else {
            YOUROBJ.extend(obj[i], defaults[i]);
        }
    }
};
YOUROBJ.extend(YOUROBJ.vars, YOUROBJ.vars2);
delete YOUROBJ.vars2;

如果您希望在加载和创建通用函数对象之前将变量添加到它,这将非常有用。

这也使第二个 YOUROBJ.vars 作为默认设置。

【讨论】:

  • “FC”指的是什么?
  • 我猜他们实际上是在他们的代码库中使用此代码,称其为FC,并将其更改为YOUROBJ 以回答问题,只是错过了一个位置。
  • 正确。更新了解决方案。
【解决方案4】:

如果你使用 jQuery,你应该检查 $.extend 函数。

你可以试试这样的:

$.fn.somePlugin = function(options){
  settings = $.extend(true, {default_values: "foo"}, options);
}

【讨论】:

    【解决方案5】:

    我还在 Javascript 中创建了一个“合并”函数用于我的一般用途:

    if (typeof Object.merge !== 'function') {
        Object.merge = function (o1, o2) { // Function to merge all of the properties from one object into another
            for(var i in o2) { o1[i] = o2[i]; }
            return o1;
        };
    } 
    

    用法:

    var eDiv = document.createElement("div");
    var eHeader = Object.merge(eDiv.cloneNode(false), {className: "header", onclick: function(){ alert("Click!"); }});
    

    它更快更脏(浅拷贝),但它可以满足我的需要。

    【讨论】:

    • 警告:像这样扩展 Object 原型是不可取的,而且通常很危险。关于这种危险以及何时/如何在sugarjs.com/native 上摆脱它的很好的文章,并在blip.tv/jsconf/… 上就这个主题进行了精彩的演讲
    • @timoxley:如果你仔细观察,它实际上并没有修改 Object 原型。
    【解决方案6】:

    我不太了解你的问题,但我认为你应该使用 $.extend 函数:

    Settings=$.extend(Settings, Type.video);
    

    这样Settings会获取Type.video属性

    【讨论】:

    • 这个问题很公平。感谢您的示例,这是完美的。
    【解决方案7】:

    简单的第一级合并(将第二个对象的键附加到第一个对象):

    var mergeObjects = function (originalObject, objectToAppend) {
        for (var item in objectToAppend) {
            if (objectToAppend.hasOwnProperty(item)) {
                originalObject[item] = objectToAppend[item];
            }
        }
    };
    

    originalObject 必须为非空!

    【讨论】:

    • 在什么情况下 hasOwnProperty 会在检查中触发错误结果? foreach 循环是否会从对象中提取其他项目?
    • 这是一个很好的参考,谢谢。所以我想我有点困惑,如果它只是一个数组,那么一个数组(比如通过你的 URL 给出的示例)如何具有继承属性?
    • @Prusprus 每个数组都继承添加到Array.prototype 的属性:"Array 实例继承自Array.prototype。与所有构造函数一样,您可以更改构造函数的原型对象以进行更改所有Array 实例。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多