Object.assign() - JavaScript - MDN Web Docs
文章推薦指數: 80 %
注意: Object.assign() 不會在來源物件屬性的值為 null 或 undefined 的時候拋出錯誤。
範例. 複製物件. var obj = { a ...
SkiptomaincontentSkiptosearchSkiptoselectlanguage給開發者的網頁技術文件JavaScriptJavaScript參考文件標準內建物件ObjectObject.assign()ArticleActions正體中文(繁體)ThispagewastranslatedfromEnglishbythecommunity.LearnmoreandjointheMDNWebDocscommunity.語法說明範例Polyfill規格瀏覽器相容性參閱RelatedTopicsStandardbuilt-inobjectsObjectPropertiesObject.prototype.constructor(en-US)
已棄用
Object.prototype.__proto__Methods
已棄用
Object.prototype.__defineGetter__()(en-US)
已棄用
Object.prototype.__defineSetter__()(en-US)
已棄用
Object.prototype.__lookupGetter__()(en-US)
已棄用
Object.prototype.__lookupSetter__()(en-US)Object.assign()Object.create()Object.defineProperties()Object.defineProperty()Object.entries()(en-US)Object.freeze()Object.fromEntries()(en-US)Object.getOwnPropertyDescriptor()(en-US)Object.getOwnPropertyDescriptors()(en-US)Object.getOwnPropertyNames()(en-US)Object.getOwnPropertySymbols()(en-US)Object.getPrototypeOf()Object.hasOwn()(en-US)Object.prototype.hasOwnProperty()Object.is()(en-US)Object.isExtensible()(en-US)Object.isFrozen()(en-US)Object.prototype.isPrototypeOf()(en-US)Object.isSealed()(en-US)Object.keys()Object.preventExtensions()Object.prototype.propertyIsEnumerable()(en-US)Object.seal()(en-US)Object.setPrototypeOf()(en-US)Object.prototype.toLocaleString()(en-US)Object.prototype.toString()(en-US)Object.prototype.valueOf()(en-US)Object.values()(en-US)語法說明範例Polyfill規格瀏覽器相容性參閱Object.assign()**Object.assign()**被用來複製一個或多個物件自身所有可數的屬性到另一個目標物件。
回傳的值為該目標物件。
語法Object.assign(target,...sources)
參數
target
目標物件
sources
來源物件
回傳值合併目標物件及(多個)來源物件所得到的最終物件。
說明如果在目標物件裡的屬性名稱(key)和來源物件的屬性名稱相同,將會被覆寫。
若來源物件之間又有相同的屬性名稱,則後者會將前者覆寫。
Object.assign()只會從來源物件將自身可列舉的屬性複製到目標物件。
此函式方法(method)使用來源物件的[[Get]]事件和目標物件的[[Set]]事件,使它將會執行getters和setters。
因此,這邊的指派(assigns)屬性不只是複製或定義新屬性。
若在合併包含getters的來源物件時,這個事件可能就不適合用來合併屬性。
至於複製屬性的定義(包含其可列舉性)到各屬性,反倒是會用到Object.getOwnPropertyDescriptor()(en-US)和Object.defineProperty()。
String和Symbol(en-US)類型的屬性都會被複製。
若發生錯誤,例如:當一個屬性不可被寫入時,將會引發TypeError(en-US)的錯誤,且目標物件剩餘的屬性將不會改變。
注意:Object.assign()不會在來源物件屬性的值為null或undefined的時候拋出錯誤。
範例複製物件varobj={a:1};
varcopy=Object.assign({},obj);
console.log(copy);//{a:1}
警告:非深層複製深層複製(deepclone)需要使用其他的替代方案,因為Object.assign()僅複製屬性值。
若來源物件的值參照到一個子物件,它只會複製該子物件的參照。
functiontest(){
leta={b:{c:4},d:{e:{f:1}}}
letg=Object.assign({},a)//淺層
leth=JSON.parse(JSON.stringify(a));//深層
console.log(g.d)//{e:{f:1}}
g.d.e=32
console.log('g.d.esetto32.')//g.d.esetto32.
console.log(g)//{b:{c:4},d:{e:32}}
console.log(a)//{b:{c:4},d:{e:32}}
console.log(h)//{b:{c:4},d:{e:{f:1}}}
h.d.e=54
console.log('h.d.esetto54.')//h.d.esetto54.
console.log(g)//{b:{c:4},d:{e:32}}
console.log(a)//{b:{c:4},d:{e:32}}
console.log(h)//{b:{c:4},d:{e:54}}
}
test();
合併物件varo1={a:1};
varo2={b:2};
varo3={c:3};
varobj=Object.assign(o1,o2,o3);
console.log(obj);//{a:1,b:2,c:3}
console.log(o1);//{a:1,b:2,c:3},目標物件本身也被改變。
有相同屬性時合併物件varo1={a:1,b:1,c:1};
varo2={b:2,c:2};
varo3={c:3};
varobj=Object.assign({},o1,o2,o3);
console.log(obj);//{a:1,b:2,c:3},屬性c為o3.c的值,最後一個出現的屬性c。
所有的屬性會被後方相同屬性名稱的值覆寫。
複製Symbol型別的屬性varo1={a:1};
varo2={[Symbol('foo')]:2};
varobj=Object.assign({},o1,o2);
console.log(obj);//{a:1,[Symbol("foo")]:2}(cf.bug1207182onFirefox)
Object.getOwnPropertySymbols(obj);//[Symbol(foo)]非不在
在屬性鏈中的不可列舉屬性不會被複製varobj=Object.create({foo:1},{//foo是obj的屬性鏈。
bar:{
value:2//bar是不可列舉的屬性,因為enumerable預設為false。
},
baz:{
value:3,
enumerable:true//baz是自身可列舉的屬性。
}
});
varcopy=Object.assign({},obj);
console.log(copy);//{baz:3}
原始型別會被包成物件varv1='abc';
varv2=true;
varv3=10;
varv4=Symbol('foo');
varobj=Object.assign({},v1,null,v2,undefined,v3,v4);
//原始型別會被打包,null和undefined則會被忽略。
//注意:只有打包成物件的字串是可列舉的,即可被複製的。
console.log(obj);//{"0":"a","1":"b","2":"c"}
任何異常將會中斷正進行的複製程序vartarget=Object.defineProperty({},'foo',{
value:1,
writable:false
});//target.foo是read-only(唯讀)屬性
Object.assign(target,{bar:2},{foo2:3,foo:3,foo3:3},{baz:4});
//TypeError:"foo"是read-only
//在指派值給target.foo時,異常(Exception)會被拋出。
console.log(target.bar);//2,第一個來源物件複製成功。
console.log(target.foo2);//3,第二個來源物件的第一個屬性複製成功。
console.log(target.foo);//1,異常在這裡拋出。
console.log(target.foo3);//undefined,複製程式已中斷,複製失敗。
console.log(target.baz);//undefined,第三個來源物件也不會被複製。
複製的存取程序varobj={
foo:1,
getbar(){
return2;
}
};
varcopy=Object.assign({},obj);
console.log(copy);
//{foo:1,bar:2},copy.bar的值,是obj.bar的getter回傳的值。
//這個函式用來複製完整的描述內容。
functioncompleteAssign(target,...sources){
sources.forEach(source=>{
letdescriptors=Object.keys(source).reduce((descriptors,key)=>{
descriptors[key]=Object.getOwnPropertyDescriptor(source,key);
returndescriptors;
},{});
//Object.assign預設會複製可列舉的Symbols。
Object.getOwnPropertySymbols(source).forEach(sym=>{
letdescriptor=Object.getOwnPropertyDescriptor(source,sym);
if(descriptor.enumerable){
descriptors[sym]=descriptor;
}
});
Object.defineProperties(target,descriptors);
});
returntarget;
}
varcopy=completeAssign({},obj);
console.log(copy);
//{foo:1,getbar(){return2}}
Polyfillpolyfill(en-US)不支援Symbol屬性,因為ES5沒有Symbol型別。
if(typeofObject.assign!='function'){
Object.assign=function(target,varArgs){//.lengthoffunctionis2
'usestrict';
if(target==null){//TypeErrorifundefinedornull
thrownewTypeError('Cannotconvertundefinedornulltoobject');
}
varto=Object(target);
for(varindex=1;index
延伸文章資訊
- 1物件的使用 - JavaScript - MDN Web Docs
JavaScript is designed on a simple object-based paradigm. An object is a collection of properties...
- 2JavaScript Object 物件 - Fooish 程式技術
JavaScript 物件(object) 是一個複合資料型態(composite data type),可以儲存不定數量的鍵值對(key-value paris),而一組鍵值對我們稱做物件的一...
- 3JavaScript Objects - W3Schools
Methods are actions that can be performed on objects. Object properties can be both primitive val...
- 4[JS] JavaScript 物件(Object) | PJCHENder 未整理筆記
[JS] JavaScript 物件(Object). Property flags and descriptors @ javascript.info; Object @ MDN > Web ...
- 5JavaScript Objects - W3Schools
JavaScript objects are containers for named values called properties. Object Methods. Objects can...