7

当且仅当目标字段存在时,javascript中有没有办法将对象中命名字段的值分配给另一个对象的相同字段。即覆盖旧值,不添加新值,使用 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"
... 
}

没有 field1 和 field3 之后的旧字段被保留。

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 次操作/秒

4

5 回答 5

7

这是单线:)

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

underscore.js你可以做:

_(theTarget).extend(_(theSource).pick( _(theTarget).keys() ));
于 2013-06-27T08:32:34.253 回答
6

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

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 版本中不起作用。

于 2013-06-27T08:48:51.000 回答
5

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

var result = {};
for (var key in theSource) {
  if (theTarget[key]) result[key] = theSource[key];
}
于 2013-06-27T08:15:42.027 回答
1
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
于 2013-06-27T09:40:07.420 回答
1

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

jQuery.overwriteOnlyExisting = function (source, target) {
    var result = {}, key;
    for (key in target) {
        result[key] = key in source ? source[key] : target[key];
    }
    return result
};
于 2013-06-27T08:39:30.860 回答