深淺拷貝的實(shí)現(xiàn)

深淺拷貝,都會(huì)進(jìn)行復(fù)制,區(qū)別在于是否會(huì)互相影響,改一個(gè),另一個(gè)也會(huì)發(fā)生改變。
淺拷貝:復(fù)制的只是原對(duì)象的引用,新舊對(duì)象的指針指向同一塊內(nèi)存空間
深拷貝:對(duì)原對(duì)象完全的復(fù)制,開(kāi)辟了新的內(nèi)存空間,引用指向另一塊內(nèi)存空間,新舊對(duì)象互不影響。

淺拷貝

實(shí)現(xiàn)方法:遍歷對(duì)象,將對(duì)象的屬性和方法放到一個(gè)新的對(duì)象中

var shallowCopy = function (obj) {
  //只拷貝對(duì)象
  if (typeof obj !== 'object') return
  //根據(jù)對(duì)象類(lèi)型判斷新建數(shù)組還是對(duì)象
  let newObj = obj instanceof Array ? [] : {}
  //遍歷對(duì)象
  for (let key in obj) {
    //判斷是obj的屬性才進(jìn)行拷貝
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key]
    }
  }
  return newObj
}
//測(cè)試
var obj = [1, 2, 3]

var newObj = shallowCopy(obj)

newObj[0] = 4

console.log(obj); //[ 1, 2, 3 ]
console.log(newObj);//[ 4, 2, 3 ]
//是不是覺(jué)得是深拷貝,感覺(jué)互不影響,來(lái)看下一個(gè)例子
var obj = [1, [2, 3], [4, 5]]

var newObj = shallowCopy(obj)

newObj[1][0] = 4

console.log(obj); //[ 1, [ 4, 3 ], [ 4, 5 ] ]
console.log(newObj);//[ 1, [ 4, 3 ], [ 4, 5 ] ]
//我們發(fā)現(xiàn),第一層的值是深拷貝,但第二層就是淺拷貝了(與Array的slice和concat方法實(shí)現(xiàn)的淺拷貝相似)

使用Array的slice和concat方法實(shí)現(xiàn)的淺拷貝

var obj = [1, [2, 3], [4, 5]]

var newObj = obj.slice()

newObj[1][0] = 4

console.log(obj); //[ 1, [ 4, 3 ], [ 4, 5 ] ]
console.log(newObj); //[ 1, [ 4, 3 ], [ 4, 5 ] ]
//concat方法實(shí)現(xiàn)與其相似

使用展開(kāi)運(yùn)算符

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

var newObj = {...obj}

newObj.obj.b = 6

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

深拷貝

  • 取巧方法(利用JSON.parse和JSON.stringify())
    JOSN 對(duì)象中的 stringify 可以把一個(gè) js 對(duì)象序列化為一個(gè) JSON 字符串,parse 可以把 JSON 字符串反序列化為一個(gè) js 對(duì)象
    缺點(diǎn):不能拷貝函數(shù)
var obj = [1, [2, 3], [4, 5]]

var newObj = JSON.parse(JSON.stringify(obj))

newObj[1][0] = 4

console.log(obj); //[ 1, [ 2, 3 ], [ 4, 5 ] ]
console.log(newObj); //[ 1, [ 4, 3 ], [ 4, 5 ] ]
  • 與淺拷貝相似,只是判斷obj的屬性如果為對(duì)象則遞歸調(diào)用深拷貝函數(shù)
var deepCopy = function (obj) {
  //只拷貝對(duì)象
  if (typeof obj !== 'object') return
  //根據(jù)對(duì)象類(lèi)型判斷新建數(shù)組還是對(duì)象
  var newObj = obj instanceof Array ? [] : {}
  //遍歷對(duì)象
  for (var key in obj) {
    //判斷是obj的屬性如果為對(duì)象則遞歸調(diào)用深拷貝函數(shù)
    if (obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
    }
  }
  return newObj
}



var obj = [1, [2, 3], [4, 5]]

var newObj = deepCopy(obj)

newObj[1][0] = 4

console.log(obj); //[ 1, [ 2, 3 ], [ 4, 5 ] ]
console.log(newObj);//[ 1, [ 4, 3 ], [ 4, 5 ] ]
  • 利用jquery的extend方法實(shí)現(xiàn)深拷貝
    語(yǔ)法:jQuery.extend( [deep ], target, object1 [, objectN ] )
    深淺拷貝對(duì)應(yīng)的參數(shù)為 [deep],值為truefalse,默認(rèn)為false,且不能顯示顯現(xiàn)出來(lái),要寫(xiě)只能寫(xiě)true
    true對(duì)應(yīng)深拷貝
    false對(duì)應(yīng)淺拷貝
var obj = [1, [2, 3], [4, 5]]
let newObj = []
$.extend(true, newObj, obj) //深拷貝示例
newObj[1][0] = 4

console.log(obj); 
console.log(newObj);
image.png
var obj = [1, [2, 3], [4, 5]]
let newObj = []
$.extend(newObj, obj) //淺拷貝示例
newObj[1][0] = 4

console.log(obj); 
console.log(newObj);
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容