老生常談之js深拷貝與淺拷貝

前言

常常會在一些網站或博客看到「深克隆」,「淺克隆」這兩個名詞,其實這個很好理解,今天咱們就在這裏分析一下js深拷貝和淺拷貝javascript

淺拷貝

咱們先以一個例子來講明js淺拷貝:java

var n = {a: 1, b: 2}
var m = n
m.a = 12
console.log(n.a) // ?
複製代碼

上面顯然 n.a 的值會變爲 12,這就是js淺拷貝。淺拷貝只是拷貝的指向對象的指針,本質上仍是指向同一個對象。正則表達式

深拷貝

一樣咱們仍是以一個例子來講明啥叫 js deep clone數據結構

var n = {a: 1, b: 2}
var m = {a: n.a, b: n.b}
m.a = 12
console.log(n.a) // ?
複製代碼

上面的輸出結果顯然仍是 1 ,m 和 n 雖然全部的屬性和值所有相同,可是它們是兩個不一樣的對象,它們在堆內存中佔據兩塊不一樣的內存地址,這就是深度拷貝。深度拷貝就是徹底複製一個新的對象出來,它們在堆內存中徹底佔據兩個不一樣的內存地址。函數

js 實現深拷貝

簡單一維數據結構

  1. 手動直接賦值

上面的 深拷貝 例子網站

  1. 利用 ES6 Object.assign() 方法
const obj = {name: 'cc', age: 24}
const newObj = Object.assign({}, obj)
obj.name = 'cc1'
newObj.name ? // cc
複製代碼

二維的數據結構及以上

  1. 簡單粗暴的方式:JSON.parse(JSON.stringify(obj))

缺點:它會對對於正則表達式類型、函數類型等沒法進行深拷貝,並且會直接丟失相應的值,還有就是它會拋棄對象的 constructorui

var obj = { a: {a: "cc"}, b: 123 }
var newObj = JSON.parse(JSON.stringify(obj))
newObj.b = 1234
console.log(obj)   // {a: {a: 'cc'}, b: 123}
console.log(newObj);    // {a: {a: 'cc'}, b: 1234}
複製代碼
  1. 利用 jQuery
// 淺拷貝
var newObj = $.extend({}, obj)

// 深拷貝
var newObj = $.extend(true, {}, obj) // 要求第一個參數必須爲true
複製代碼
  1. 本身動手實現一個簡單深拷貝函數
function deepClone(obj){
  if(typeof obj !== "object" || obj === null) return    
  let newObj = obj instanceof Array ? [] : {}
  for(let key in obj){
     if(obj.hasOwnProperty(key)){
        newObj[key] = typeof obj[key] === "object" && obj[key] !== null ? deepClone(obj[key]) : obj[key]
    }      
  }  
  return newObj
}
let obj = {a: 1, b: function(){}, c: {d: 2}}
deepClone(obj)  // {a: 1, b: function(){}, c: {d: 2}}
複製代碼

對於深拷貝來講最經常使用的就是這些方法,固然還有其餘的一些庫,好比 deepCopylodash等,這裏就不深究。spa

相關文章
相關標籤/搜索