var obj1 = {
a: 'cat'
b: 'dog'
};
var obj2 = {
b: 'dragon'
c: 'cow'
};
如何從obj2
到obj1
添加屬性,而不改寫爲obj1
。輸出應該像console.log(obj1)
=>{a: 'cat', b: 'dog', c: 'cow'}
和console.log(obj2)
=>{b: 'dragon', c: 'cow'}
var obj1 = {
a: 'cat'
b: 'dog'
};
var obj2 = {
b: 'dragon'
c: 'cow'
};
如何從obj2
到obj1
添加屬性,而不改寫爲obj1
。輸出應該像console.log(obj1)
=>{a: 'cat', b: 'dog', c: 'cow'}
和console.log(obj2)
=>{b: 'dragon', c: 'cow'}
就檢查它是否存在第一,如果它不添加它!
for (key in obj2) {
if (!obj1[key]) obj1[key] = obj2[key]
}
由於RobG在評論中指出,這是不行的,如果你的價值觀是falsey(0,假的,不確定的,空,「」,等等),它會跳過他們。如果你總是使用字符串,就像在你的例子這將是確定的,但你很可能會成爲安全和全面:
for (key in obj2) {
if (!(obj1.hasOwnProperty(key))) {
obj1[key] = obj2[key]
}
}
從一個對象的屬性複製到另一個有Object.assign。但是,如果源上存在相同名稱的屬性,它將覆蓋目標對象的值。
您可以創建一個assignSoft方法,該方法不會覆蓋現有屬性的值。以下內容基於MDN的Object.assign polyfill。它似乎有點長,因爲它儘可能地實現了對於Object.assign的ECMAScript算法。
此外,與內置的Object.assign一樣,它只做一個「淺」副本,因此不會複製對象值,因此會分配參考。
if (typeof Object.assignSoft != 'function') {
Object.assignSoft = function(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
// Don't copy if property exists on target
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey) && !Object.prototype.hasOwnProperty.call(to, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
var obj = Object.assignSoft({a:'a',b:'b'},{b:'bb',c:'c'});
console.log(obj); // {a:'a',b: 'b',c:'c'}
更緊湊(雖然不太嚴格的)版本,只需要一個源對象。要添加支持多源,遍歷傳入的參數
if (!Object.assignSoft) {
Object.assignSoft = function(target, source) {
Object.keys(source).forEach(function(key){
if (!target.hasOwnProperty(key)) {
target[key] = source[key];
}
});
return target;
}
}
var obj = Object.assignSoft({a:'a',b:'b'},{b:'bb',c:'c'});
console.log(obj); // {a:'a',b: 'b',c:'c'}
解決方案:
obj1 = {...obj2, ...obj1};
該解決方案只有當你知道什麼是預期值可能是工作,例如你知道他們都將是非空字符串。這使用對象擴展語法。您需要確保最後包含obj1
。你可能需要一個像babel這樣的轉譯器,直到所有瀏覽器(IE ...)都趕上爲止。
let obj1 = {
a: 'cat',
b: 'dog'
};
let obj2 = {
b: 'dragon',
c: 'cow'
};
obj1 = {...obj2, ...obj1};
console.log('obj1:', obj1);
console.log('obj2:', obj2);
順序很重要,IE的任何版本都不支持'...'標點符號。 :-( – RobG
@RobG,我加了一個關於可能需要babel的警告,謝謝。 –
@RobG好點,我會改變我的回答反映這一點。 – AllTheTime
我試過這個,它沒有工作。你可以再檢查一次嗎? –
@ChristAdam它絕對有效...... https://jsfiddle.net/szycsmtc/ – AllTheTime