成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解JS深淺拷貝

JackJiang / 1810人閱讀

摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。結(jié)果如下擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝那么我們可以看到和展開(kāi)原算符對(duì)于深淺拷貝的結(jié)果是一樣。

JS中數(shù)據(jù)類型

基本數(shù)據(jù)類型: undefined、null、Boolean、Number、String和Symbol(ES6)

引用數(shù)據(jù)類型: Object(Array, Date, RegExp, Function)

深淺拷貝

深淺拷貝只是針對(duì)引用類型的,因?yàn)橐妙愋褪谴娣旁诙褍?nèi)存中,在棧地址有一個(gè)或者多個(gè)地址來(lái)指向推內(nèi)存的某一數(shù)據(jù)

淺拷貝:

被復(fù)制對(duì)象的所有變量都含有與原來(lái)的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用仍然指向原來(lái)的對(duì)象。

淺拷貝僅僅復(fù)制所考慮的對(duì)象,而不復(fù)制它所引用的對(duì)象,如果你修改了“副本”的值,那么原來(lái)的對(duì)象也會(huì)被修改

深拷貝:

深拷貝是一個(gè)整個(gè)獨(dú)立的對(duì)象拷貝,深拷貝會(huì)拷貝所有的屬性,并拷貝屬性指向的動(dòng)態(tài)分配的內(nèi)存。當(dāng)對(duì)象和它所引用的對(duì)象一起拷貝時(shí)即發(fā)生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。

深拷貝把要復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。如果你修改了“副本”的值,那么原來(lái)的對(duì)象不會(huì)被修改,兩者是相互獨(dú)立的。

用例子看深淺拷貝 賦值實(shí)現(xiàn)淺拷貝
let arr = [22, 44, 66, 88];
let co = arr;
co[0] = 11;
console.log(arr, co);

結(jié)果如圖:

我們本來(lái)想把 arr 賦值給 co ,當(dāng)我們修改co數(shù)組中第一個(gè)元素時(shí),卻發(fā)現(xiàn)了原始數(shù)組arr發(fā)生了改變
很顯然,這就是一個(gè)淺拷貝的例子

原理:
對(duì)于引用類型,賦值操作符只是把存放在棧內(nèi)容中的指針賦值給另外一個(gè)變量。
所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。
也就可以說(shuō)兩個(gè)變量在共用著同一個(gè)數(shù)據(jù),這就是淺拷貝。
JSON實(shí)現(xiàn)深拷貝
let arr = [22, 44, 66, 88];
let jso = JSON.parse(JSON.stringify(arr));
jso[0] = 11;
console.log(arr, jso);

結(jié)果如圖:

對(duì)比之前賦值的結(jié)果,我們發(fā)現(xiàn)原來(lái)的數(shù)組arr并沒(méi)有被改變,可以說(shuō)兩者是相互獨(dú)立的
很顯然,這就是一個(gè)深拷貝的例子

原理:
JSON.parse() 方法用于將一個(gè) JSON 字符串轉(zhuǎn)換為對(duì)象。
JSON.stringify() 方法用于將 JavaScript 值(通常為對(duì)象或數(shù)組)轉(zhuǎn)換為 JSON 字符串。
在JSON.stringify()完成后,對(duì)象就轉(zhuǎn)為了字符串,也就可以說(shuō)實(shí)實(shí)在在的復(fù)制了一個(gè)值,不存在引用之說(shuō)。
再利用JSON.parse()轉(zhuǎn)為對(duì)象,這樣達(dá)到深拷貝的目的

JSON實(shí)現(xiàn)深拷貝的缺陷:
來(lái)看下面例子:

let obj = {
    nul: null,
    und: undefined,
    sym: Symbol("sym"),
    str: "str",
    bol: true,
    num: 45,
    arr: [1, 4],
    reg: /[0-9]/,
    dat: new Date(),
    fun: function() {},  
}
console.log(JSON.parse(JSON.stringify(obj)))

結(jié)果如圖:

我們可以發(fā)現(xiàn)有些屬性被忽略了:

undefined

symbol

function

可以看得出來(lái)JSON實(shí)現(xiàn)深拷貝也有不足之處

ES6新特性實(shí)現(xiàn)拷貝 Object.assign()

Object.assign方法用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)。
Object.assign(target, ...sources)
target目標(biāo)對(duì)象。 sources源對(duì)象。 返回的是目標(biāo)對(duì)象

let obj = {
    a: {
        a1: "a1"
    },
    b: "b"
}
let ass = Object.assign({}, obj);
ass.a.a1 = "aaa";
aconsole.log(obj, ass);

我們看下結(jié)果:

我們可以看到a1的值被改變,而b的值沒(méi)有被改變,說(shuō)明了:

Obejct.assign()只能對(duì)一層進(jìn)行深拷貝 
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝
展開(kāi)運(yùn)算符(...)

對(duì)象的擴(kuò)展運(yùn)算符(...)用于取出參數(shù)對(duì)象的所有可遍歷屬性,拷貝到當(dāng)前對(duì)象之中。

let obj = {
    a: {
        a1: "a1"
    },
    b: "b"
}
let ass = {...obj};
ass.a.a1 = "aaa";
ass.b = "bbb"

結(jié)果如下:

擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝 
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝

那么我們可以看到Object.assign()和展開(kāi)原算符對(duì)于深淺拷貝的結(jié)果是一樣。
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝
所以要慎用這兩個(gè)來(lái)進(jìn)行拷貝!!!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100714.html

相關(guān)文章

  • 深入理解 Javascript 之 JS深淺拷貝

    摘要:動(dòng)手實(shí)現(xiàn)深拷貝利遞歸來(lái)實(shí)現(xiàn)對(duì)對(duì)象或數(shù)組的深拷貝。遞歸思路對(duì)屬性中所有引用類型的值進(jìn)行遍歷,直到是基本類型值為止。深拷貝只對(duì)對(duì)象自有屬性進(jìn)行拷貝測(cè)試數(shù)據(jù)拷貝方式其實(shí)也是一種繼承的方式,當(dāng)然繼承還是有其他方法的感謝支持 深淺拷貝 基本類型 & 引用類型 ECMAScript中的數(shù)據(jù)類型可分為兩種: 基本類型:undefined,null,Boolean,String,Number,Symb...

    Tikitoo 評(píng)論0 收藏0
  • js深淺復(fù)制

    摘要:總結(jié)綜上所述,數(shù)組的深拷貝比較簡(jiǎn)單,方法沒(méi)有什么爭(zhēng)議,對(duì)象的深拷貝,比較好的方法是用的方法實(shí)現(xiàn),或者遞歸實(shí)現(xiàn),比較簡(jiǎn)單的深復(fù)制可以使用實(shí)現(xiàn)參考資料知乎中的深拷貝和淺拷貝深入剖析的深復(fù)制 深淺復(fù)制對(duì)比 因?yàn)镴avaScript存儲(chǔ)對(duì)象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致 obj 和obj1 指向同一塊內(nèi)存地址。我的理解是,這有點(diǎn)類似數(shù)據(jù)雙向綁定,改變了其中一方的內(nèi)容,都是在原來(lái)的內(nèi)存基礎(chǔ)上做...

    Apollo 評(píng)論0 收藏0
  • 一篇文章徹底搞懂JS深淺拷貝和const

    摘要:圖數(shù)據(jù)類型圖引用類型深淺拷貝問(wèn)題不知道什么是深拷貝和淺拷貝的請(qǐng)先去并在調(diào)試臺(tái)自己操作一下,這篇文章只會(huì)說(shuō)明為何中會(huì)有這種問(wèn)題。所以有的時(shí)候我們?yōu)榱吮苊鉁\拷貝,會(huì)用一些方式實(shí)現(xiàn)深拷貝。 首先要了解的js基礎(chǔ) 基本數(shù)據(jù)類型:Object、undefined、null、Boolean、Number、String、Symbol (ES6新加) Object包括: Array 、Date 、R...

    MyFaith 評(píng)論0 收藏0
  • 復(fù)習(xí)Javascript專題(四):js中的深淺拷貝

    摘要:基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì),這類引用類型數(shù)據(jù)。它會(huì)拋棄對(duì)象的。另外,查資料過(guò)程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì)Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對(duì)于字符串來(lái)說(shuō),是值的復(fù)制,而對(duì)于對(duì)象來(lái)說(shuō)則是對(duì)對(duì)象地址的復(fù)制;而深拷貝的話,它不...

    MobService 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<