亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

JavaScript對象拷貝與Object.assign用法實例分析

2024-05-06 16:44:56
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript對象拷貝與Object.assign用法。分享給大家供大家參考,具體如下:

深拷貝與淺拷貝

在 JavaScript 中,對于基本數據類型(undefined、null、boolean、number、string)來說,在變量中存儲的就是這個變量本身的值,復制是對值的復制,不存在深淺之說。但C系語言的共同特點中有,存儲引用類型(對象),實際中在變量里存的是它的地址。因此對 JavaScript 中的復雜數據類型(object)來說,也會有淺拷貝和深拷貝的概念:淺拷貝指兩個不同的變量存的是同一個對象的地址,即兩個變量指向同一塊內存區域;深拷貝則是重新分配了一塊內存區域來存儲復制后的對象,兩個變量存的是真正的兩個互不影響的變量。

p.s. 有些資料認為淺拷貝是重新分配內存,并把原對象中的各個屬性進行依次復制而不進行遞歸復制屬性值是對象的情況,也就是只復制對象的最外面一層。本文將這種情況歸于“深拷貝和淺拷貝的中間情況”,文中以“是否劃分新的內存”為界限劃分深淺拷貝,這種劃分方式與 C/C++、C#、Java 等C系語言保持概念一致。

淺拷貝在JavaScript中的實現

淺拷貝在js中很簡單,例如:

let objA = {  name: '對象A',  content: '我是A'};let copyA = objA;console.log(objA.name); // ==> "對象A"console.log(copyA.name); // ==> "對象A"

如此即得到了objA的一份淺拷貝copyA,由于指向的是同一個對象,因此在修改objA的同時也是修改了copyA,反之亦然。

Object.assign()

Object.assign(target, …sources) MDN上對該方法的描述是 將所有可枚舉屬性的值從一個或多個源對象復制到目標對象,String類型和 Symbol 類型的屬性都會被拷貝, 并且該方法會忽略值為 或者 undefined 的源對象。例如:

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)]

Object.assign 的深拷貝與淺拷貝

注意前面說的是可枚舉屬性,這是一個介于完全的深拷貝和完全的淺拷貝之間的方法:如果我們把它的第一個參數target設置為一個空對象 {},同時保證剩余的源對象sources中的屬性類型不包含引用類型,則該方法的返回值就是一個與源對象相同的但并不在同一塊內存空間另一個對象,即獲得了源對象的深拷貝。但是,如果源對象的屬性中包含某個對象,也就是這個屬性的值指向某個對象,就像下面這樣:

var obj = {  name: 'obj name',  content: {    a: 1,    b: 2  }};

則使用 Object.assign({}, obj) 時,返回的目標對象中的content屬性與源對象obj中的content屬性指向的同一塊內存區域,即對obj下的content屬性進行了淺拷貝。因此針對深拷貝,需要使用其他方法,比如自己實現一個深拷貝的方法,或者使用 JSON.parse(JSON.stringify(obj)), 因為 Object.assign()拷貝的是屬性值。

Object.assign 的屬性覆蓋

如果目標對象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性,因此可以用來合并對象(常用的一個場景是使用reducers更新React應用的狀態)。

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 }

關于對象的繼承屬性和不可枚舉屬性

前文有提到,Object.assign 拷貝的是對象的可枚舉屬性,該方法使用源對象的 [[Get]] 和目標對象的 [[Set]],所以它會調用相關 getter 和 setter。因此,不如說它是分配屬性,而不僅僅是復制或定義新的屬性。如果合并源包含 getter,這可能使其不適合將新屬性合并到原型中,將屬性定義(包括其可枚舉性)復制到原型應使用Object.getOwnPropertyDescriptor() 和 Object.defineProperty() ,因此 Object.assign 不能拷貝對象的繼承屬性,例如:

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 }

當源對象是原始數據類型時

ECMAScript 有 5 種原始類型(primitive type): Undefined、NullBoolean、Number 和 String。當Object.assign的源對象是原始類型時,源對象會被包裝成“對象”,對應的鍵是它在源對象中的索引值:

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" }

當拷貝過程中發生異常時

在出現錯誤的情況下,例如,如果屬性不可寫,會引發TypeError,異常會打斷后續的拷貝任務。如果在引發錯誤之前添加了任何屬性,則可以更改target對象。

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// 注意這個異常是在拷貝第二個源對象的第二個屬性時發生的。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,第三個源對象更是不會被拷貝到的。

希望本文所述對大家JavaScript程序設計有所幫助。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区久久精品| 国产精品久久久久影院日本| 日韩一区av在线| 国产综合久久久久| 国产精品va在线播放| 8090成年在线看片午夜| 欧美福利小视频| 国产精品一区二区久久久| 高清亚洲成在人网站天堂| 三级精品视频久久久久| 欧美黑人一级爽快片淫片高清| 欧美在线精品免播放器视频| 久久国产一区二区三区| 久久色免费在线视频| 亚洲欧美精品一区二区| 韩日欧美一区二区| 91在线视频精品| 亚洲桃花岛网站| 日韩av网站电影| 国产精品va在线播放我和闺蜜| 欧美激情亚洲一区| 秋霞成人午夜鲁丝一区二区三区| 精品自拍视频在线观看| 久久久国产91| 成人中心免费视频| 久久久亚洲精品视频| 日韩理论片久久| 91精品久久久久久久久不口人| 视频直播国产精品| 18性欧美xxxⅹ性满足| 乱亲女秽乱长久久久| 国产欧美日韩免费| 欧美性在线观看| 中文字幕久热精品在线视频| 国产精品中文字幕久久久| 欧美视频专区一二在线观看| 疯狂做受xxxx高潮欧美日本| 亚洲二区在线播放视频| 精品久久中文字幕久久av| 精品欧美激情精品一区| 狠狠综合久久av一区二区小说| 日韩精品亚洲视频| 国产精品午夜视频| 日韩精品福利网站| 深夜福利国产精品| 精品国产成人av| 中文字幕精品影院| 7777精品久久久久久| 亚洲欧美日韩国产中文| 欧美一级视频在线观看| 欧美精品videosex极品1| 日韩视频在线一区| 欧洲精品毛片网站| 成人激情电影一区二区| 国产精品久久中文| 91亚洲精品视频| www.久久久久久.com| 精品网站999www| 亚洲男人天堂古典| 亚洲成人黄色在线观看| 青青青国产精品一区二区| 伊人久久久久久久久久久久久| 亚洲精品色婷婷福利天堂| 久久综合88中文色鬼| 国产精品扒开腿做爽爽爽的视频| 中文字幕久久久| 国产精品99久久久久久www| 欧美性极品少妇精品网站| 日韩精品在线免费| 欧美视频13p| 国产亚洲成精品久久| 日韩av在线最新| 欧美成人精品三级在线观看| 日韩av网站导航| 国产香蕉一区二区三区在线视频| 91久久久久久久一区二区| 国产精品香蕉在线观看| 亚洲成人激情在线观看| 国产精品久久久久久一区二区| 亚洲高清久久久久久| 在线观看欧美www| 亚洲国产精品va在线观看黑人| 国产精品一区二区三区成人| 51久久精品夜色国产麻豆| 黑人狂躁日本妞一区二区三区| 久久久久久美女| 亚洲天堂av在线免费| 久久精品免费电影| 这里只有精品在线观看| 日本一本a高清免费不卡| 日本午夜在线亚洲.国产| 久久人人爽人人爽爽久久| 欧美三级欧美成人高清www| 91久热免费在线视频| 国产精品亚洲综合天堂夜夜| 91久久精品国产91性色| 国产剧情日韩欧美| 欧美一区二区影院| 国产精品一区二区久久久久| 热99精品只有里视频精品| 亚洲国产黄色片| 日本欧美国产在线| 欧美视频在线观看免费网址| 欧美激情免费视频| 欧美亚洲视频在线看网址| 91大神在线播放精品| 国产91|九色| 国产精品jvid在线观看蜜臀| 日韩福利在线播放| 国模视频一区二区| 日韩欧美在线国产| 日本不卡视频在线播放| 欧美激情第一页xxx| 久久国产精品久久久久久| 91视频免费在线| 久久精品美女视频网站| 国产精品一香蕉国产线看观看| 久久中文久久字幕| 国产成人精品久久亚洲高清不卡| 久久久中精品2020中文| 国产69精品久久久久9| 这里只有视频精品| 亚洲天堂男人天堂| 成人免费看吃奶视频网站| 日韩一级黄色av| 亚洲国产精品久久91精品| 欧美日韩国产专区| 91精品久久久久久久久久入口| 亚洲图片欧洲图片av| 亚洲深夜福利在线| 亚洲最大av在线| 97久久精品在线| 亚洲欧美制服综合另类| 欧美性猛交xxxx免费看漫画| 青青草精品毛片| 另类专区欧美制服同性| 91精品国产综合久久香蕉| 亚洲一区二区三区在线免费观看| 欧美在线免费看| 国产一区私人高清影院| 欧美激情在线观看| 国产精品日韩欧美| 欧美性一区二区三区| 91欧美精品成人综合在线观看| 亚洲国产欧美久久| 欧美日韩激情视频| 国产精品美乳一区二区免费| 亚洲第一中文字幕在线观看| 欧美综合在线观看| 欧美另类69精品久久久久9999| 久久九九国产精品怡红院| 欧美日韩美女在线| 久久这里有精品视频| 成人免费看黄网站| 国产精品7m视频| 综合国产在线视频| 亚洲人成伊人成综合网久久久| 国产91色在线|| 91免费人成网站在线观看18| 欧美综合在线第二页| 日韩极品精品视频免费观看| 2019中文字幕在线观看| 欧美性猛交视频| 日韩av在线不卡|