Object.assign()
Object.assign() 方法用於將所有可枚舉屬性的值從一個或多個源對象分配到目標對象。它將返回目標對象。
Object.assign 方法只會拷貝源對象自身的並且可枚舉的屬性到目標對象。該方法使用源對象的[[Get]]和目標對象的[[Set]],所以它會調用相關 getter 和 setter。因此,它分配屬性,而不僅僅是複製或定義新的屬性。如果合併源包含getter,這可能使其不適合將新屬性合併到原型中。
爲了將屬性定義(包括其可枚舉性)複製到原型,應使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
String類型和 Symbol 類型的屬性都會被拷貝。
更新對象
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // { a: 1, b: 4, c: 5 }
複製一個對象
const obj = { a: 1, b: 2, c: 3 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1, b: 2, c: 3 }
合併對象
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };
const obj = Object.assign(obj1, obj2, obj3);
console.log(obj1); // { a: 1, b: 2, c: 3 }
console.log(obj); // { a: 1, b: 2, c: 3 }, 目標對象自身也會改變。
拷貝
Object.assign拷貝的屬性是有限制的,只拷貝源對象的自身屬性(不拷貝繼承屬性),也不拷貝不可枚舉的屬性(enumerable: false)。
Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: false,
value: 'hello'
})
)
// { b: 'c' }
屬性名爲 Symbol 值的屬性,也會被Object.assign拷貝
Object.assign({ a: 'b', b: 'c'}, { [Symbol('c')]: 'd' })
// { a: 'b', b: 'c', Symbol(c): 'd' }
總結
1.爲對象添加屬性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
2.爲對象添加方法
Object.assign(mainContent.prototype, {
oneMethod(arg1, arg2) {
},
anotherMethod() {
}
});
等同於下面的寫法
mainContent.prototype.oneMethod = function (arg1, arg2) {
};
mainContent.prototype.anotherMethod = function () {
};
3.複製一個對象
const obj = { a: 1, b: 2, c: 3 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1, b: 2, c: 3 }
4.合併對象
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };
const obj = Object.assign(obj1, obj2, obj3);
console.log(obj1); // { a: 1, b: 2, c: 3 }
console.log(obj); // { a: 1, b: 2, c: 3 }, 目標對象自身也會改變。
5.爲屬性指定默認值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
let options = Object.assign({}, DEFAULTS, options);
}
MDN
拷貝訪問器
const obj = {
foo: 1,
get bar() {
return 2;
}
};
let copy = Object.assign({}, obj);
console.log(copy); // { foo: 1, bar: 2 } copy.bar的值來自obj.bar的getter函數的返回值
// 下面這個函數會拷貝所有自有屬性的屬性描述符
function completeAssign(target, ...sources) {
sources.forEach(source => {
let descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {});
// Object.assign 默認也會拷貝可枚舉的Symbols
Object.getOwnPropertySymbols(source).forEach(sym => {
let descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(target, descriptors);
});
return target;
}
copy = completeAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }