Object.assign() - JavaScript - MDN Web Docs

文章推薦指數: 80 %
投票人數:10人

注意: 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



請為這篇文章評分?