日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript深入理解对象方法——Object.assign()

發(fā)布時間:2025/4/16 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript深入理解对象方法——Object.assign() 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Object.assign()

Object.assign()方法用于將所有可枚舉屬性的值從一個或多個源對象復(fù)制到目標(biāo)對象。它將返回目標(biāo)對象。

語法

Object.assign(target, ...sources)

參數(shù)

  • target
    目標(biāo)對象。
  • sources
    源對象。

返回值

目標(biāo)對象。

描述

如果目標(biāo)對象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性。

Object.assign 方法只會拷貝源對象自身的并且可枚舉的屬性到目標(biāo)對象。該方法使用源對象的[[Get]]和目標(biāo)對象的[[Set]],所以它會調(diào)用相關(guān) getter 和 setter。因此,它分配屬性,而不僅僅是復(fù)制或定義新的屬性。如果合并源包含getter,這可能使其不適合將新屬性合并到原型中。為了將屬性定義(包括其可枚舉性)復(fù)制到原型,應(yīng)使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。

String類型和 Symbol 類型的屬性都會被拷貝。

在出現(xiàn)錯誤的情況下,例如,如果屬性不可寫,會引發(fā)TypeError,如果在引發(fā)錯誤之前添加了任何屬性,則可以更改target對象。

注意,Object.assign 會跳過那些值為 null 或 undefined 的源對象。

示例

復(fù)制一個對象

var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }

深拷貝問題

針對深拷貝,需要使用其他方法,因為 Object.assign()拷貝的是屬性值。假如源對象的屬性值是一個指向?qū)ο蟮囊?#xff0c;它也只拷貝那個引用值。

function test() {'use strict';let obj1 = { a: 0 , b: { c: 0}};let obj2 = Object.assign({}, obj1);console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}obj1.a = 1;console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}obj2.a = 2;console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}obj2.b.c = 3;console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}// Deep Cloneobj1 = { a: 0 , b: { c: 0}};let obj3 = JSON.parse(JSON.stringify(obj1));obj1.a = 4;obj1.b.c = 4;console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}} }test();

合并對象

var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 };var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目標(biāo)對象自身也會改變。

合并具有相同屬性的對象

var o1 = { a: 1, b: 1, c: 1 }; var o2 = { b: 2, c: 2 }; var o3 = { c: 3 };var obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 }

屬性被后續(xù)參數(shù)中具有相同屬性的其他對象覆蓋。

var o1 = { a: 1 }; var o2 = { [Symbol('foo')]: 2 };var obj = Object.assign({}, o1, o2); console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox) Object.getOwnPropertySymbols(obj); // [Symbol(foo)]

繼承屬性和不可枚舉屬性是不能拷貝的

var obj = Object.create({foo: 1}, { // foo 是個繼承屬性。bar: {value: 2 // bar 是個不可枚舉屬性。},baz: {value: 3,enumerable: true // baz 是個自身可枚舉屬性。} });var copy = Object.assign({}, obj); console.log(copy); // { baz: 3 }

原始類型會被包裝為對象

var v1 = "abc"; var v2 = true; var v3 = 10; var v4 = Symbol("foo")var obj = Object.assign({}, v1, null, v2, undefined, v3, v4); // 原始類型會被包裝,null 和 undefined 會被忽略。 // 注意,只有字符串的包裝對象才可能有自身可枚舉屬性。 console.log(obj); // { "0": "a", "1": "b", "2": "c" }

異常會打斷后續(xù)拷貝任務(wù)

var target = Object.defineProperty({}, "foo", {value: 1,writable: false }); // target 的 foo 屬性是個只讀屬性。Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4}); // TypeError: "foo" is read-only // 注意這個異常是在拷貝第二個源對象的第二個屬性時發(fā)生的。console.log(target.bar); // 2,說明第一個源對象拷貝成功了。 console.log(target.foo2); // 3,說明第二個源對象的第一個屬性也拷貝成功了。 console.log(target.foo); // 1,只讀屬性不能被覆蓋,所以第二個源對象的第二個屬性拷貝失敗了。 console.log(target.foo3); // undefined,異常之后 assign 方法就退出了,第三個屬性是不會被拷貝到的。 console.log(target.baz); // undefined,第三個源對象更是不會被拷貝到的。

拷貝訪問器

var obj = {foo: 1,get bar() {return 2;} };var copy = Object.assign({}, obj); // { foo: 1, bar: 2 } // copy.bar的值來自obj.bar的getter函數(shù)的返回值 console.log(copy); // 下面這個函數(shù)會拷貝所有自有屬性的屬性描述符 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 默認也會拷貝可枚舉的SymbolsObject.getOwnPropertySymbols(source).forEach(sym => {let descriptor = Object.getOwnPropertyDescriptor(source, sym);if (descriptor.enumerable) {descriptors[sym] = descriptor;}});Object.defineProperties(target, descriptors);});return target; }var copy = completeAssign({}, obj); console.log(copy); // { foo:1, get bar() { return 2 } }

Polyfill

if (typeof Object.assign != 'function') {// Must be writable: true, enumerable: false, configurable: trueObject.defineProperty(Object, "assign", {value: function assign(target, varArgs) { // .length of function is 2'use strict';if (target == null) { // TypeError if undefined or nullthrow 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 nullfor (var nextKey in nextSource) {// Avoid bugs when hasOwnProperty is shadowedif (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {to[nextKey] = nextSource[nextKey];}}}}return to;},writable: true,configurable: true}); }

總結(jié)

以上是生活随笔為你收集整理的JavaScript深入理解对象方法——Object.assign()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。