摘要:淺拷貝和淺拷貝的問(wèn)題,不僅在日常應(yīng)用中需要注意,而且在面試和筆試中也常被用來(lái)考察應(yīng)聘者,屬于文體兩開(kāi)花的。基本數(shù)據(jù)類型引用數(shù)據(jù)類型等等基本數(shù)據(jù)類型是按值訪問(wèn)的,對(duì)其的拷貝會(huì)直接復(fù)制其值保存在新變量中。方法手工遍歷法方法方法方法方法
淺拷貝和淺拷貝的問(wèn)題,不僅在日常應(yīng)用中需要注意,而且在面試和筆試中也常被用來(lái)考察應(yīng)聘者,屬于“文體兩開(kāi)花”的points。
什么是深拷貝和淺拷貝呢?名稱 | 定義 |
---|---|
淺拷貝 | 對(duì)基本數(shù)據(jù)類型進(jìn)行值傳遞,對(duì)引用數(shù)據(jù)類型進(jìn)行引用傳遞形式的拷貝 |
深拷貝 | 對(duì)基本數(shù)據(jù)類型進(jìn)行值傳遞,對(duì)引用數(shù)據(jù)類型,創(chuàng)建一個(gè)新的對(duì)象,并復(fù)制其內(nèi)容 |
也就是說(shuō),對(duì)于a,讓b對(duì)a進(jìn)行拷貝,之后當(dāng)a發(fā)生變化,若b也跟著發(fā)生變化,就是淺拷貝;若a發(fā)生變化,b不變化,那就是深拷貝。
基本數(shù)據(jù)類型 | 引用數(shù)據(jù)類型 |
---|---|
Number、String、Boolean、Null、Undefined等 | Object、Array、Function等 |
基本數(shù)據(jù)類型是按值訪問(wèn)的,對(duì)其的拷貝會(huì)直接復(fù)制其值保存在新變量中。例如Number類型:
var a = 1; b = a; console.log(b); // 1 a = 2; console.log(b); //1 (a的變化不會(huì)影響b的值)
而“引用數(shù)據(jù)類型”是按引用訪問(wèn)的,對(duì)其直接進(jìn)行拷貝只會(huì)操作引用地址,而不是值本身。例如Array類型:
var a = [1, 2, 3]; b = a; console.log(a); // [1, 2, 3] console.log(b); // [1, 2, 3] a[0] = 2; console.log(a); // [2, 2, 3] console.log(b); // [2, 2, 3] (對(duì)數(shù)組a的改動(dòng)也影響了數(shù)組b)
其原理如下圖所示:
那么,如何對(duì)引用數(shù)據(jù)類型實(shí)現(xiàn)深拷貝呢?
顯而易見(jiàn)的思路是:既然是因?yàn)橐玫刂吩斐闪藷o(wú)法深拷貝,那就拋開(kāi)引用地址,直接對(duì)值進(jìn)行遍歷,將其拷貝給新的變量。方法1: 手工遍歷法
let a = [1, [2, 3], 4]; const copy = (obj) => { let newObj = obj.constructor === Array ? [] : {} if(typeof obj !== "object") { return; } for(let i in obj) { newObj[i] = typeof obj[i] === "object" ? copy(obj[i]) : obj[i] } return newObj } let b = copy(a); a[1][0] = 3; console.log(a); // [1, [3, 3], 4] console.log(b); // [1, [2, 3], 4]方法2: JSON方法
let a = [1, [2, 3], 4]; const copy = (obj) => { let _obj = JSON.stringify(obj) let newObj = JSON.parse(_obj) return newObj } let b = copy(a); a[1][0] = 3; console.log(a); // [1, [3, 3], 4] console.log(b); // [1, [2, 3], 4]方法3: JQuery-extend方法
let a = [1, [2, 3], 4]; b = $.extend(true,[],a); a[1][0] = 3; console.log(a); // [1, [3, 3], 4] console.log(b); // [1, [2, 3], 4]
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109212.html
摘要:在中可以通過(guò)添加一個(gè)參數(shù)來(lái)實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝 在JavaScript中,對(duì)于Object和Array這類引用類型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對(duì)象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說(shuō)的淺拷貝和深拷貝 淺拷貝(shallow...
摘要:說(shuō)明外層數(shù)組拷貝的是實(shí)例說(shuō)明元素拷貝是引用深拷貝在堆中重新分配內(nèi)存,并且把源對(duì)象所有屬性都進(jìn)行新建拷貝,拷貝后的對(duì)象與原來(lái)的對(duì)象完全隔離,互不影響。中的方法可以實(shí)現(xiàn)深拷貝,源碼原理也是遞歸使用淺拷貝。 1.淺拷貝 當(dāng)把數(shù)組或?qū)ο蠛?jiǎn)單賦值給其他變量的時(shí)候,實(shí)際上進(jìn)行的是淺拷貝,淺拷貝是拷貝引用,只是將拷貝后的引用指向同一個(gè)對(duì)象實(shí)例,彼此間的操作還會(huì)互相影響。 分為兩種情況:直接拷貝源對(duì)象...
摘要:而大多數(shù)實(shí)際項(xiàng)目中,我們想要的結(jié)果是兩個(gè)變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對(duì)象的屬性,而深拷貝則遞歸復(fù)制了所有層級(jí)。 為什么會(huì)用到淺拷貝和深拷貝 首先來(lái)看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
摘要:而大多數(shù)實(shí)際項(xiàng)目中,我們想要的結(jié)果是兩個(gè)變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對(duì)象的屬性,而深拷貝則遞歸復(fù)制了所有層級(jí)。 為什么會(huì)用到淺拷貝和深拷貝 首先來(lái)看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
摘要:而大多數(shù)實(shí)際項(xiàng)目中,我們想要的結(jié)果是兩個(gè)變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對(duì)象的屬性,而深拷貝則遞歸復(fù)制了所有層級(jí)。 為什么會(huì)用到淺拷貝和深拷貝 首先來(lái)看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
閱讀 1412·2021-11-04 16:11
閱讀 3083·2021-10-12 10:11
閱讀 3014·2021-09-29 09:47
閱讀 1641·2021-09-22 15:40
閱讀 1046·2019-08-29 15:43
閱讀 2831·2019-08-29 13:50
閱讀 1611·2019-08-29 13:28
閱讀 2717·2019-08-29 12:54