溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript對象的深拷貝和淺拷貝總結(jié)

發(fā)布時間:2021-09-14 09:52:35 來源:億速云 閱讀:117 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“JavaScript對象的深拷貝和淺拷貝總結(jié)”,在日常操作中,相信很多人在JavaScript對象的深拷貝和淺拷貝總結(jié)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JavaScript對象的深拷貝和淺拷貝總結(jié)”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

  什么是對象的拷貝?

  將一個對象賦值給另外一個對象, 我們稱之為對象的拷貝。

  什么是深拷貝, 什么是淺拷貝?

  我們假設(shè)將A對象賦值給B對象。淺拷貝是指, 修改B對象的屬性和方法會影響到A對象的屬性和方法, 我們稱之為淺拷貝

  以下兩種情況都屬于淺拷貝:

  1、默認(rèn)情況下對象之間的 直接賦值 都是淺拷貝。

  let A = {

  name: 'zyx',

  age: 20

  }

  let B = A

  console.log(B) // {name: "zyx", age: 20}

  //修改B的 name 屬性

  B.name = 'ls'

  //A 也收到影響

  console.log(A) // {name: "ls", age: 20}

  console.log(B) // {name: "ls", age: 20}

   賦值操作(包括對象作為參數(shù)、返回值),不會開辟新的內(nèi)存空間,他只是賦值了對象的引用.也就是除了B這個名字之外,沒有其他的內(nèi)存開銷,修改了A也就影響了B,修改了B,也就影響了A.

  2、如果 對象的屬性包含了引用數(shù)據(jù)類型(數(shù)組、對象) ,那么哪怕不是直接賦值操作,而是開辟了一層新的內(nèi)存空間,也就是說只拷貝了A對象的一層,這仍然屬于淺拷貝。

  let A = {

  name: 'ls',

  age: 20,

  hobbies: ['dance','basketball','read'],

  dogs:{

  name: '大黃',

  color: 'yellow'

  }

  }

  let B = {}

  //定義一個函數(shù),把A對象的屬性復(fù)制一份給B

  function extend(obj1,obj2){

  for(var key in obj1){

  obj2[key] = obj1[key]

  }

  }

  extend(A,B)

  //修改B對象中的引用類型數(shù)據(jù) ,A對象也收到影響

  B.dogs.color = 'red'

  B.hobbies[0] = 'sing'

  console.log(B)

  console.log(A)

  修改B對象中的引用類型數(shù)據(jù) ,A對象也收到影響,屬于淺拷貝。

  3、ES6中新增的 Object.assign() 也是對象的淺拷貝

  Object.assign 方法用于對象的合并,將源對象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對象(target)。 Object.assign 方法的第一個參數(shù)是目標(biāo)對象,后面的參數(shù)都是源對象。 注意,如果目標(biāo)對象與源對象有同名屬性,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性。

  const obj1 = {a: {b: 1}};

  const obj2 = Object.assign({}, obj1);

  obj1.a.b = 2;

  obj2.a.b // 2

  上面代碼中,源對象 obj1 的 a 屬性的值是一個對象, Object.assign 拷貝得到的是這個對象的引用。這個對象的任何變化,都會反映到目標(biāo)對象上面。

  4、擴(kuò)展運算符(...)

  利用擴(kuò)展運算符可以在構(gòu)造字面量對象時,進(jìn)行克隆或者屬性拷貝 ,屬于淺拷貝。

  var obj = {a:1,b:{c:1}}

  var obj2 = {...obj};

  obj.a=2;

  console.log(obj); //{a:2,b:{c:1}}

  console.log(obj2); //{a:1,b:{c:1}}

  obj.b.c = 2;

  console.log(obj); //{a:2,b:{c:2}}

  console.log(obj2); //{a:1,b:{c:2}}

  5、Array.prototype.slice()

  slice() 方法返回一個新的數(shù)組對象,這一對象是一個由 begin和 end(不包括end)決定的原數(shù)組的淺拷貝。原始數(shù)組不會被改變。

  深拷貝是指, 修改B對象的屬性和方法不會影響到A對象的屬性和方法, 我們稱之為深拷貝。

  以下兩種情況都屬于深拷貝:

  5.1、默認(rèn)情況下一個 對象的屬性如果是基本數(shù)據(jù)類型 , 那么進(jìn)行復(fù)制(拷貝),都是深拷貝。

  如果A對象的屬性都是基本數(shù)據(jù)類型(Number、String等),此時要想深拷貝一份A給B,該怎么做呢,在這種 要拷貝的對象A只有基本類型的數(shù)據(jù)時 ,只需要在內(nèi)存中開辟一塊空間存儲B就行了。

  let A = {

  name: 'zyx',

  age: 20

  }

  let B = {}

  //定義一個函數(shù),把A對象的屬性復(fù)制一份給B

  function extend(obj1,obj2){

  for(var key in obj1){

  obj2[key] = obj1[key]

  }

  }

  extend(A,B)

  console.log(B) // {name: "zyx", age: 20}

  B.name = 'ls'

  console.log(B) // {name: "ls", age: 20}

  console.log(A) // {name: "zyx", age: 20}

  這樣就實現(xiàn)了深拷貝。

  5.2、如果 要拷貝的對象本身又包含了引用數(shù)據(jù)類型 ,即對象又包含數(shù)組或者對象,層層嵌套的情況下,想要實現(xiàn)對象的深拷貝,可以采用 遞歸 的方式進(jìn)行深拷貝。

  let A = {

  name: 'ls',

  age: 20,

  hobbies: ['dance','basketball','read'],

  dogs:{

  name: '大黃',

  color: 'yellow'

  }

  }

  let B = {}

  //定義一個函數(shù),把A對象的屬性復(fù)制一份給B

  function extend(obj1,obj2){

  for(var key in obj1){

  var item = obj1[key]

  if(item instanceof Array){

  obj2[key] = []

  extend(item,obj2[key])

  }else if(item instanceof Object){

  obj2[key] = {}

  extend(item,obj2[key])

  }else{

  obj2[key] = item

  }

  }

  }

  extend(A,B)

  B.dogs.color = 'red'

  B.hobbies[0] = 'sing'

  console.log(B)

  console.log(A)

  運行發(fā)現(xiàn),修改B對象的引用數(shù)據(jù)類型,不會影響到A對象,完成深拷貝。

  我們可以對深拷貝的代碼進(jìn)行封裝優(yōu)化

  function deepClone(obj){

  let cloneObj = {}

  for(let key in obj){

  if(typeof obj[key] === 'object'){

  cloneObj[key] = deepClone(obj[key])

  }else{

  cloneObj[key] = obj[key]

  }

  }

  return cloneObj

  }

  5.3、通過JSON.stringify實現(xiàn)深拷貝。

  JSON.stringify()是目前前端開發(fā)過程中最常用的深拷貝方式,原理是把一個對象序列化成為一個JSON字符串,將對象的內(nèi)容轉(zhuǎn)換成字符串的形式再保存在磁盤上,再用JSON.parse()反序列化將JSON字符串變成一個新的對象。

  var obj1 = {

  a:1,

  b:[1,2,3]

  }

  var str = JSON.stringify(obj1)

  var obj2 = JSON.parse(str)

  console.log(obj2); //{a:1,b:[1,2,3]}

  obj1.a=2

  obj1.b.push(4);

  console.log(obj1); //{a:2,b:[1,2,3,4]}

  console.log(obj2); //{a:1,b:[1,2,3]}

到此,關(guān)于“JavaScript對象的深拷貝和淺拷貝總結(jié)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI