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

資訊專欄INFORMATION COLUMN

關于JavaScript的淺拷貝和深拷貝

shenhualong / 2672人閱讀

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

前言

要理解 JavaScript中淺拷貝和深拷貝的區(qū)別,首先要明白JavaScript的數(shù)據(jù)類型。JavaScript有兩種數(shù)據(jù)類型,基礎數(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.基本類型值和引用類型值的復制

1.1基本類型值

基本類型值是指在棧內(nèi)存保存的簡單數(shù)據(jù)段,在復制基本類型值的時候,會開辟出一個新的內(nèi)存空間,將值復制到新的內(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;

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

1.2引用類型值
引用類型值是保存在堆內(nèi)存中的對象,變量保存的只是指向該內(nèi)存的地址,在復制引用類型值的時候,其實只復制了指向該內(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’;

從上面例子看出,當一個變量的值是引用類型值,把它復制給另外一個變量,復制的只是指向儲存對象內(nèi)存的地址,所以復制完成后,改變它的值,會影響復制了它的值的變量。
注意:如果有兩個變量的值是引用類型值,就算它們的值完全相同,它們也是不相等的,因為它們指向的內(nèi)存地址不同,例子:

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

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

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

2.1 對象淺拷貝

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

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

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,這是因為Object.assign()方法只是淺層拷貝,a.name是一個棧對象的引用,賦值給b時,b.name也同樣是這個棧對象的引用,很多時候,我們不想讓這種事情發(fā)生,所以我們就需要用到對象的深拷貝。

2.2 對象深拷貝

2.2.1 萬能的for循環(huán)實現(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 擴展運算符實現(xiàn)對象的深拷貝

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

運行結果如下:

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返回一個新數(shù)組的特性來實現(xiàn)拷貝,但是如果數(shù)組嵌套了對象或者數(shù)組的話用concat、slice拷貝只要有修改會引起新舊數(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ù)組元素是基本類型,就會拷貝一份,互不影響,而如果是對象或者數(shù)組,就會只拷貝對象和數(shù)組的引用,這樣我們無論在新舊數(shù)組進行了修改,兩者都會發(fā)生變化。這種叫淺拷貝 。
深拷貝就是指完全的拷貝一個對象,即使嵌套了對象,兩者也相互分離,修改一個對象的屬性,也不會影響另一個。

3.2 數(shù)組深拷貝

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

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)

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

轉載請注明本文地址:http://systransis.cn/yun/108613.html

相關文章

  • JavaScript的淺拷貝和深拷貝

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

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

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

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

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

    xeblog 評論0 收藏0
  • 關于js的淺拷貝與深拷貝

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

    summerpxy 評論0 收藏0
  • js的淺拷貝和深拷貝和應用場景

    摘要:而大多數(shù)實際項目中,我們想要的結果是兩個變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復制一層對象的屬性,而深拷貝則遞歸復制了所有層級。 為什么會用到淺拷貝和深拷貝 首先來看一下如下代碼 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元查看
<