国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關(guān)于JavaScript的淺拷貝和深拷貝

shenhualong / 2662人閱讀

摘要:引用類型值引用類型值是保存在堆內(nèi)存中的對象,變量保存的只是指向該內(nèi)存的地址,在復(fù)制引用類型值的時(shí)候,其實(shí)只復(fù)制了指向該內(nèi)存的地址。

前言

要理解 JavaScript中淺拷貝和深拷貝的區(qū)別,首先要明白JavaScript的數(shù)據(jù)類型。JavaScript有兩種數(shù)據(jù)類型,基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型。
js的基本類型:undefined,null,string,boolean,number,symbol(es6新增),保存在棧內(nèi)存中
js的引用類型:Object類型, Array類型,Date類型,RegExp類型,F(xiàn)unction類型,基本包裝對象(Boolean類型,Number類型,String類型),單體內(nèi)置對象(Global對象,Math對象),保存在堆內(nèi)存空間中

1.基本類型值和引用類型值的復(fù)制

1.1基本類型值

基本類型值是指在棧內(nèi)存保存的簡單數(shù)據(jù)段,在復(fù)制基本類型值的時(shí)候,會(huì)開辟出一個(gè)新的內(nèi)存空間,將值復(fù)制到新的內(nèi)存空間。

var a = 1;
var b = a;
a = 2;
console.log(a);//輸出2;
console.log(b);//輸出1;

var a = 1;

var b = a;

a = 2;

從上面例子看出,當(dāng)一個(gè)變量的值是基本類型,把它復(fù)制給另一個(gè)變量,復(fù)制完成后改變它的值,不會(huì)影響已經(jīng)復(fù)制了它的值的變量。

1.2引用類型值
引用類型值是保存在堆內(nèi)存中的對象,變量保存的只是指向該內(nèi)存的地址,在復(fù)制引用類型值的時(shí)候,其實(shí)只復(fù)制了指向該內(nèi)存的地址。

var a = {
   name: "Kitty",
   age: "20",
   sex: "man"
};
var b = a;
a.name = "Jack";
console.log(a);//輸出{name: "Jack",age: 20,sex: "man"}
console.log(b);//輸出{name: "Jack",age: 20,sex: "man"}

var a = {name: ‘Kitty’,age: ‘20’,sex: ‘man’};

var b = a;

a.name = ‘Jack’;

從上面例子看出,當(dāng)一個(gè)變量的值是引用類型值,把它復(fù)制給另外一個(gè)變量,復(fù)制的只是指向儲(chǔ)存對象內(nèi)存的地址,所以復(fù)制完成后,改變它的值,會(huì)影響復(fù)制了它的值的變量。
注意:如果有兩個(gè)變量的值是引用類型值,就算它們的值完全相同,它們也是不相等的,因?yàn)樗鼈冎赶虻膬?nèi)存地址不同,例子:

2. 對象的淺拷貝與深拷貝

當(dāng)一個(gè)變量是對象,如果像上面那樣直接將一個(gè)變量賦值給另一個(gè)變量,如果改變某個(gè)變量的值,另外一個(gè)變量也會(huì)跟著改變,如果我們不想發(fā)生這種情況,就需要寫一個(gè)函數(shù)用來拷貝對象。

深拷貝和淺拷貝的示意圖大致如下:

2.1 對象淺拷貝

var a = {name:"wanger"}
var b = Object.assign({}, a)
a===b // false
b.name = "zhangsan"
a.name //"wanger"

上面代碼將原始對象拷貝到一個(gè)空對象,就得到了原始對象的克隆,這時(shí)候a與b指向的是不同的棧對象,所以對b.name重新復(fù)制也不會(huì)影響到a.name。但是如果a.name是一個(gè)對象的引用,而不是一個(gè)字符串,那么上面的代碼也會(huì)遇到一些問題,參考如下代碼:

var a = {name:{firstName:"wang",lastName:"er"}}
var b = Object.assign({}, a)
a===b // false
b.name.firstName = "zhang"
a.name.firstName //"zhang"

b.name.firstName又影響到了a.name.firstName,這是因?yàn)镺bject.assign()方法只是淺層拷貝,a.name是一個(gè)棧對象的引用,賦值給b時(shí),b.name也同樣是這個(gè)棧對象的引用,很多時(shí)候,我們不想讓這種事情發(fā)生,所以我們就需要用到對象的深拷貝。

2.2 對象深拷貝

2.2.1 萬能的for循環(huán)實(shí)現(xiàn)對象的深拷貝

var obj = {
  name: "FungLeo",
  sex: "man",
  old: "18"
}
var obj2 = copyObj(obj)
function copyObj(obj) {
  let res = {}
  for (var key in obj) {
    res[key] = obj[key]
  }
  return res
}

2.2.2 JSON.parse(JSON.stringify(objectToClone))

var obj = {
  name: "FungLeo",
  sex: "man",
  old: "18"
}
var obj2 = JSON.parse(JSON.stringify(obj))

2.2.3 擴(kuò)展運(yùn)算符實(shí)現(xiàn)對象的深拷貝

var obj = {
  name: "FungLeo",
  sex: "man",
  old: "18"
}
var { ...obj2 } = obj
obj.old = "22"
console.log(obj)
console.log(obj2)

運(yùn)行結(jié)果如下:

3. 數(shù)組的淺拷貝與深拷貝

3.1 數(shù)組淺拷貝

var arr = ["old", 1, true, null, undefined];
var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一樣的效果;
new_arr[0] = "new";
console.log(arr); // ["old", 1, true, null, undefined]
console.log(new_arr); // ["new", 1, true, null, undefined]

數(shù)組的淺拷貝,可用concat、slice返回一個(gè)新數(shù)組的特性來實(shí)現(xiàn)拷貝,但是如果數(shù)組嵌套了對象或者數(shù)組的話用concat、slice拷貝只要有修改會(huì)引起新舊數(shù)組都一起改變了,比如:

var arr = [{old: "old"}, ["old"]];
var new_arr = arr.concat();
arr[0].old = "new";
new_arr[1][0] = "new";
console.log(arr); // [{old: "new"}, ["new"]]
console.log(new_arr); // [{old: "new"}, ["new"]]

如果數(shù)組元素是基本類型,就會(huì)拷貝一份,互不影響,而如果是對象或者數(shù)組,就會(huì)只拷貝對象和數(shù)組的引用,這樣我們無論在新舊數(shù)組進(jìn)行了修改,兩者都會(huì)發(fā)生變化。這種叫淺拷貝 。
深拷貝就是指完全的拷貝一個(gè)對象,即使嵌套了對象,兩者也相互分離,修改一個(gè)對象的屬性,也不會(huì)影響另一個(gè)。

3.2 數(shù)組深拷貝

3.2.1 利用擴(kuò)展運(yùn)算符...對數(shù)組中嵌套對象進(jìn)行深拷貝

var arr=[{a:1,b:2},{c:1,d:2}];
    var arr2=[];
    
    arr.forEach(item=>{
      var {...obj}=item;
      arr2.push(obj);
    })
    arr2[1].d=7
    
    console.log(arr,arr2)

3.2.2 利用lodash庫的cloneDeep方法

var arr=[{a:1,b:2},{c:1,d:2}];
var arr2=_.cloneDeep(arr)   

arr2[1].d=7;
console.log(arr,arr2)

3.2.3 JSON.parse(JSON.stringify(objectToClone))

var arr=[{a:1,b:2},{c:1,d:2}];
var arr2=JSON.parse(JSON.stringify(arr));
    
arr2[1].d=7;
console.log(arr,arr2)

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108613.html

相關(guān)文章

  • JavaScript的淺拷貝和深拷貝

    摘要:在中可以通過添加一個(gè)參數(shù)來實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝 在JavaScript中,對于Object和Array這類引用類型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...

    ernest.wang 評論0 收藏0
  • JavaScript的淺拷貝和深拷貝

    摘要:但是進(jìn)行的是淺拷貝,拷貝的是屬性值。對象展開符深拷貝的實(shí)現(xiàn)方式手動(dòng)復(fù)制轉(zhuǎn)成再轉(zhuǎn)回來只有可以轉(zhuǎn)成格式的對象才可以這樣用,像沒辦法轉(zhuǎn)成沒被改到使用方法避免相互引用對象導(dǎo)致死循環(huán),如的情況四參考關(guān)于的淺拷貝和深拷貝 一、理解 淺拷貝只復(fù)制指向某個(gè)對象的指針,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對象,新對象跟原對象不共享內(nèi)存,修改新對象不會(huì)改到原對象。...

    GeekQiaQia 評論0 收藏0
  • JS中的淺拷貝和深拷貝

    摘要:說明外層數(shù)組拷貝的是實(shí)例說明元素拷貝是引用深拷貝在堆中重新分配內(nèi)存,并且把源對象所有屬性都進(jìn)行新建拷貝,拷貝后的對象與原來的對象完全隔離,互不影響。中的方法可以實(shí)現(xiàn)深拷貝,源碼原理也是遞歸使用淺拷貝。 1.淺拷貝 當(dāng)把數(shù)組或?qū)ο蠛唵钨x值給其他變量的時(shí)候,實(shí)際上進(jìn)行的是淺拷貝,淺拷貝是拷貝引用,只是將拷貝后的引用指向同一個(gè)對象實(shí)例,彼此間的操作還會(huì)互相影響。 分為兩種情況:直接拷貝源對象...

    xeblog 評論0 收藏0
  • 關(guān)于js的淺拷貝與深拷貝

    摘要:原文地址淺拷貝和深拷貝只針對像這樣的復(fù)雜對象的簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。淺拷貝通過來實(shí)現(xiàn)淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對像Object, Array這樣的復(fù)雜對象的.簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。 淺拷貝 通過 Object.ass...

    summerpxy 評論0 收藏0
  • js的淺拷貝和深拷貝和應(yīng)用場景

    摘要:而大多數(shù)實(shí)際項(xiàng)目中,我們想要的結(jié)果是兩個(gè)變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對象的屬性,而深拷貝則遞歸復(fù)制了所有層級。 為什么會(huì)用到淺拷貝和深拷貝 首先來看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...

    MartinDai 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<