【问题标题】:Javascript: Overwrite ONLY existing fields in one object with the fields in anotherJavascript:仅用另一个对象中的字段覆盖一个对象中的现有字段
【发布时间】:2013-06-27 08:10:30
【问题描述】:

javascript中有没有办法 当且仅当目标字段存在时,将对象中命名字段的值分配给另一个对象的相同字段。 IE。覆盖旧值,不添加新值,使用 ideomatic 构造,单行(javascript 和/或 jQuery 专用),绝不循环,甚至 for-in。

var theSource = {
 field1: "TEXT",
 field2: "VAL",
 field3: "ZZ",
 field4: "4",
 field5: "5"
},
theTarget = {
 field2: "0",
 field3: "",
 field4: null,
 field5: undefined
};

类似

var result = jQuery.overwriteOnlyExisting(theTarget, theSource);
result === {
 field2: "VAL"
 field3: "ZZ"
... 
}

保留字段 1 和字段 3 之后的旧字段。

jQuery.extend - 可以覆盖值,但它也会复制新字段。

我们有哪些选择?

http://jsbin.com/owivat/1/edit(下划线) - 我喜欢这个,现在是时候找到 jquery 方式了。

结果:

_.extend(theTarget, _(theSource).pick(_(theTarget).keys()));

142,850 次操作/秒

Object.keys(theTarget).map(function(a) { if (a in theSource) theTarget[a] = theSource[a]; });

403,243 次操作/秒

【问题讨论】:

  • 为什么...而且绝不会循环,即使是for-in
  • 你应该使用underscorejs.org/#eachbackbonejs.org/#Model-has。基本上它是源上的 for-in 循环和目标上的 object.hasOwnProperty。
  • @inf3rno 很高兴知道,但坚持使用 jQuery :)
  • 只有标准的js我们可以做到:Object.keys(theTarget).map(function(a){ if(theSource[a]) theTarget[a]=theSource[a]})跨度>
  • jquery 只是用于 DOM 操作,所以你不会用 jquery 来做这件事......顺便说一句,使用标准 javascript 是一件容易的事......

标签: javascript jquery object


【解决方案1】:

这里是单线 :)

for(var propertyName in theTarget)theTarget[propertyName]&&(theTarget[propertyName]=theSource[propertyName]);

underscore.js 你可以这样做:

_(theTarget).extend(_(theSource).pick( _(theTarget).keys() ));

【讨论】:

  • 单线的概念是错误的 :) 单线是我们可以用 map/splice/filter/regex 等做的很酷的事情。谢谢你让它变得有趣。
  • @gr9zev 查看下划线,它非常适合函数式编程
  • 查看 cmets 到 OP。仍然可以“挑选”一个对象作为参数吗?如果必须手动列出所有字段 - 这是无稽之谈。
  • 所以,测试了 jsbin.com/owivat/1/edit 并且它可以工作,但同时使用 jquery 和 _ 仍然是开销......
【解决方案2】:

好的!单线!没有可见的循环!

Object.keys(theTarget).map(function(a){ if(theSource[a]) theTarget[a]=theSource[a]})

虽然地图在其来源中有一个循环,但我敢肯定。但我认为这是没有可见循环结构的唯一方法。虽然它滥用了 javascript 的全局命名空间,因此很脏。

好的,更好:

Object.keys(theTarget).map(function(a){ if(Object.keys(theSource).indexOf(a)) theTarget[a]=theSource[a]})

更简洁

keys(theTarget).map(function(a){ if(a in theSource) theTarget[a]=theSource[a]}) 

虽然 keys() 和 Array#indexOf 在旧的 ecma 版本中不起作用。

【讨论】:

  • 这更好,但我已经看到了 js 的魔力,必须对 'if(theSource[a])' 进行一些内置检查。另外请注意 Poetro 的回答,此解决方案不适用于 theSource[a] === '', 0, null 等
  • 好的,这里有一个更好的。 Array#indexOf 应该可以完美运行。
  • 我不认为这可以重构为更简洁。
  • 我们会看到)但它很好,使用 Object 更好: Object.keys(theTarget).map(function(a){ if (a in theSource) theTarget[a] = theSource[a ]; });
【解决方案3】:

你可以手动完成,我不明白为什么“没有循环”。 jQuery 也在以某种方式循环:

var result = {};
for (var key in theSource) {
  if (theTarget[key]) result[key] = theSource[key];
}

【讨论】:

    【解决方案4】:

    您必须检查source 的密钥,检查它们是否存在(不是真实,因为它们不会复制0''falsenullundefinedNaN) 并将该值复制到结果对象。由于您不想覆盖源或目标,因此请不要修改它们。

    jQuery.overwriteOnlyExisting = function (source, target) {
        var result = {}, key;
        for (key in target) {
            result[key] = key in source ? source[key] : target[key];
        }
        return result
    };
    

    【讨论】:

    • 有效点,这就是为什么我尝试依赖更精细的 js 和 jquery 机制,而不是陷入“忘记某事”的陷阱。
    【解决方案5】:
    var theSource = {
     field1: "TEXT",
     field2: "VAL",
     field3: "ZZ",
     field4: "4",
     field5: "5"
    },
    theTarget = {
     field2: "0",
     field3: "",
     field4: null,
     field5: undefined
    };
    
    var overrideExistingProperties = function (theTarget, theSource){
        for (var property in theSource)
            if (theSource.hasOwnProperty(property) && theTarget.hasOwnProperty(property))
                theTarget[property] = theSource[property];
    };
    
    overrideExistingProperties(theTarget, theSource);
    result = theTarget; //if you don't want to clone
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      相关资源
      最近更新 更多