2013-06-27 84 views
7

當JavaScript中存在指定字段的值時,javascript 是否有辦法將另一個對象的相同字段中的值分配給另一個對象的相同字段。即覆蓋舊值,不添加新值,使用意識構造,單行(對javascript和/或jQuery特別),並且不會循環,甚至是for-in。場3後Javascript:只改寫一個對象中的現有字段,並且使用另一個對象中的字段

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" 
... 
} 

NO Field 1和老油田被保留。

jQuery.extend - 可以覆蓋值,但它也會複製新的字段。

我們在這裏有哪些選擇?

http://jsbin.com/owivat/1/edit(下劃線) - 我喜歡這個,現在是時候去找jQuery的方式了。

結果:

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

142850 OPS /秒​​

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

403243 OPS /秒​​

+0

爲什麼* ...並且絕不會循環,甚至是in-in *? – fcalderan

+2

你應該使用http://underscorejs.org/#each和http://backbonejs.org/#Model-has。基本上它是源代碼中的for-in循環和目標上的object.hasOwnProperty。 – inf3rno

+0

@ inf3rno酷知道,但堅持與jQuery :) –

回答

7

這裏是一個班輪:)

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

underscore.js你可以這樣做:

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

這是錯誤的單線理念:)一個襯墊很酷我們可以用map/splice/filter/regex等來做的事情。謝謝你讓它變得有趣。 –

+0

@ gr9zev檢出下劃線,這對功能性編程很有用 –

+0

查看對OP的評論。仍然可以'選擇'獲取一個對象作爲參數?如果必須手動列出所有字段 - 這是不存在的。 –

5

你可以做手工,我不明白爲什麼 「沒有循環」。 jQuery是循環也以某種方式或其他:

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

你必須去通過source的鑰匙,檢查它們是否存在(如果它們不是truthy,那麼它不會複製到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 
}; 
+0

有效的點,這就是爲什麼我試圖依靠更復雜js和jquery的機制,不要陷入「遺忘某物」的陷阱。 –

3

好的! oneliner!沒有可見的循環!

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]}) 

雖然鍵()和陣列#的indexOf不會在老年ECMA版本。

+0

更好,但我見過js魔法,必須是一些內置檢查'if(theSource [a])'。另外請注意Poetro的答案,這個解決方案不適用於Source [a] ==='',0,null等等 –

+1

好的,這是一個更好的解決方案。 Array#indexOf應該完美地工作。 –

+0

我不認爲這可以被重構爲一個更簡潔。 –

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 
相關問題