最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript對(duì)象拷貝與Object.assign用法實(shí)例分析

 更新時(shí)間:2018年06月20日 10:13:05   作者:憶之逸之  
這篇文章主要介紹了JavaScript對(duì)象拷貝與Object.assign用法,結(jié)合實(shí)例形式分析了javascript深拷貝與淺拷貝以及Object.assign的功能與相關(guān)使用技巧,需要的朋友可以參考下

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

深拷貝與淺拷貝

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

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

淺拷貝在JavaScript中的實(shí)現(xiàn)

淺拷貝在js中很簡(jiǎn)單,例如:

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

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

Object.assign()

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

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 的深拷貝與淺拷貝

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

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

則使用 Object.assign({}, obj) 時(shí),返回的目標(biāo)對(duì)象中的content屬性與源對(duì)象obj中的content屬性指向的同一塊內(nèi)存區(qū)域,即對(duì)obj下的content屬性進(jìn)行了淺拷貝。因此針對(duì)深拷貝,需要使用其他方法,比如自己實(shí)現(xiàn)一個(gè)深拷貝的方法,或者使用 JSON.parse(JSON.stringify(obj)), 因?yàn)?Object.assign()拷貝的是屬性值。

Object.assign 的屬性覆蓋

如果目標(biāo)對(duì)象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來(lái)的源的屬性將類(lèi)似地覆蓋早先的屬性,因此可以用來(lái)合并對(duì)象(常用的一個(gè)場(chǎng)景是使用reducers更新React應(yīng)用的狀態(tài))。

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 }

關(guān)于對(duì)象的繼承屬性和不可枚舉屬性

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

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

當(dāng)源對(duì)象是原始數(shù)據(jù)類(lèi)型時(shí)

ECMAScript 有 5 種原始類(lèi)型(primitive type): Undefined、Null、Boolean、Number String。當(dāng)Object.assign的源對(duì)象是原始類(lèi)型時(shí),源對(duì)象會(huì)被包裝成“對(duì)象”,對(duì)應(yīng)的鍵是它在源對(duì)象中的索引值:

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

當(dāng)拷貝過(guò)程中發(fā)生異常時(shí)

在出現(xiàn)錯(cuò)誤的情況下,例如,如果屬性不可寫(xiě),會(huì)引發(fā)TypeError,異常會(huì)打斷后續(xù)的拷貝任務(wù)。如果在引發(fā)錯(cuò)誤之前添加了任何屬性,則可以更改target對(duì)象。

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

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Javascript顯示和隱藏ul列表的方法

    Javascript顯示和隱藏ul列表的方法

    這篇文章主要介紹了Javascript顯示和隱藏ul列表的方法,涉及javascript針對(duì)頁(yè)面元素遍歷及顯示與隱藏的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 小程序云開(kāi)發(fā)部署攻略(圖文教程)

    小程序云開(kāi)發(fā)部署攻略(圖文教程)

    微信小程序的云開(kāi)發(fā)功能剛剛上線,這篇文章主要介紹了小程序云開(kāi)發(fā)部署攻略(圖文教程),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • JavaScript的類(lèi)型、值和變量小結(jié)

    JavaScript的類(lèi)型、值和變量小結(jié)

    這篇文章主要介紹了JavaScript的類(lèi)型、值和變量小結(jié)的相關(guān)資料,需要的朋友可以參考下
    2015-07-07
  • JavaScript 數(shù)組的深度復(fù)制解析

    JavaScript 數(shù)組的深度復(fù)制解析

    一般情況下,使用 “=” 可以實(shí)現(xiàn)賦值。但對(duì)于數(shù)組、對(duì)象、函數(shù)等這些引用類(lèi)型的數(shù)據(jù),這個(gè)符號(hào)就不好使了。這篇文章主要介紹了JavaScript 數(shù)組的深度復(fù)制解析的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • javascript實(shí)現(xiàn)右下角廣告框效果

    javascript實(shí)現(xiàn)右下角廣告框效果

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)右下角廣告框效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • JS學(xué)習(xí)筆記之?dāng)?shù)組去重實(shí)現(xiàn)方法小結(jié)

    JS學(xué)習(xí)筆記之?dāng)?shù)組去重實(shí)現(xiàn)方法小結(jié)

    這篇文章主要介紹了JS學(xué)習(xí)筆記之?dāng)?shù)組去重實(shí)現(xiàn)方法,結(jié)合實(shí)例形式總結(jié)分析了javascript數(shù)組去重的5種常見(jiàn)實(shí)現(xiàn)方法及相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • javascript修改IMG標(biāo)簽的src問(wèn)題

    javascript修改IMG標(biāo)簽的src問(wèn)題

    javascript修改IMG標(biāo)簽的SRC,在IE6下面圖片修改正常,但在IE7和Firefox下面卻不刷新,下面有個(gè)解決方法,大家可以參考下
    2014-03-03
  • JS將時(shí)間秒轉(zhuǎn)換成天小時(shí)分鐘秒的字符串

    JS將時(shí)間秒轉(zhuǎn)換成天小時(shí)分鐘秒的字符串

    最近小編接到這樣的項(xiàng)目需求,接口返回的數(shù)據(jù)中時(shí)間單位為秒,但前端顯示的時(shí)候需要更人性化的帶有單位(天,小時(shí),分鐘,秒)的字符串;下面小編給大家?guī)?lái)實(shí)例代碼,感興趣的朋友跟隨小編一起看看吧
    2019-07-07
  • 2007/12/23更新創(chuàng)意無(wú)限,簡(jiǎn)單實(shí)用(javascript log)

    2007/12/23更新創(chuàng)意無(wú)限,簡(jiǎn)單實(shí)用(javascript log)

    在javascript開(kāi)發(fā)過(guò)程中,如果總是使用alert的方式調(diào)試程序,在某些簡(jiǎn)單的程序中是可行的. 但是在通常的項(xiàng)目很復(fù)雜,這種方式已經(jīng)很難滿(mǎn)足,企業(yè)級(jí)開(kāi)發(fā)的需要。
    2007-12-12
  • 詳解JS中的compose函數(shù)和pipe函數(shù)用法

    詳解JS中的compose函數(shù)和pipe函數(shù)用法

    這篇文章主要介紹了JS中的compose函數(shù)和pipe函數(shù)用法,想深入了解Javascript的同學(xué),可以參考下
    2021-04-04

最新評(píng)論

临湘市| 泊头市| 钟祥市| 芷江| 故城县| 青铜峡市| 茌平县| 正定县| 安塞县| 太原市| 梁山县| 眉山市| 许昌县| 读书| 大荔县| 宣城市| 襄垣县| 华蓥市| 公主岭市| 万州区| 海伦市| 安泽县| 历史| 胶州市| 井冈山市| 蒙山县| 蓬莱市| 怀宁县| 海安县| 乐陵市| 广州市| 安庆市| 广汉市| 肥西县| 龙里县| 会同县| 南乐县| 峨边| 龙川县| 磐石市| 沅陵县|