Javascript:仅使用另一个对象中的字段覆盖一个对象中的现有字段

问题描述 投票:7回答:5

当且仅当目标字段存在时,javascript中是否有一种方法可以将对象中的命名字段的值分配给另一个对象的相同字段。即覆盖旧值,不添加新值,使用ideomatic结构,one-liners(特别适用于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 Ops / sec

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

403,243 Ops / sec

javascript jquery object
5个回答
7
投票

这是单线:)

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

underscore.js你可以做:

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

5
投票

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

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

3
投票

OK!一个班轮!没有可见的循环!

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版本。


1
投票

你必须通过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
};

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
© www.soinside.com 2019 - 2024. All rights reserved.