乐趣区

关于javascript:浅拷贝与深拷贝

赋值

var o1 = {
    age:1,
    language : [1,[2,3],[4,5]],
}
var o2 = o1
o2.age = 2
o2.language[2] = [6,7]
console.log(o1.age) //2
console.log(o1.language)//[1,[2,3],[6,7]]

浅拷贝

办法一:手撕

function shallowCopy(src) {var dst = {};
   for (var prop in src) {if (src.hasOwnProperty(prop)) {dst[prop] = src[prop];
       }
   }
   return dst;
}

办法二:Object.assign({},who)(对象)

var o1 = {
    age:1,
    language : [1,[2,3],[4,5]],
}
var o2 = Object.assign({}, o1)
o2.age = 2
o2.language[2] = [6,7]
console.log(o1.age) //1
console.log(o1.language) //[1,[2,3],[6,7]]

办法三:三点运算符 (对象)

var o1 = {
    age:1,
    language : [1,[2,3],[4,5]],
}
var o2 = {...o1}
o2.age = 2
o2.language[2] = [6,7]
console.log(o1.age) //1
console.log(o1.language) //[1,[2,3],[6,7]]

办法四:Array.prototype.concat()(数组)

var o1 = [
    1,
    [1,[2,3],[4,5]]
]
var o2 = o1.concat()
o2[0] = 2
o2[1][2] = [6,7]
console.log(o1[0]) //1
console.log(o1[1]) //[1,[2,3],[6,7]]

办法五:Array.prototype.slice()(数组)

var o1 = [
    1,
    [1,[2,3],[4,5]]
]
var o2 = o1.slice()
o2[0] = 2
o2[1][2] = [6,7]
console.log(o1[0]) //1
console.log(o1[1]) //[1,[2,3],[6,7]]

深拷贝

办法一:JSON.parse(JSON.stringify())(数组 + 对象)

用 JSON.stringify 将对象转成 JSON 字符串,再用 JSON.parse() 把字符串解析成对象,一去一来,新的对象产生了,而且对象会开拓新的栈,实现深拷贝。

var o1 = {
    age:1,
    language : [1,[2,3],[4,5]],
}
var o2 = JSON.parse(JSON.stringify(o1))
o2.age = 2
o2.language[2] = [6,7]
console.log(o1.age) //1
console.log(o1.language) //[1,[2,3],[4,5]]
var o1 = [
    1,
    [1,[2,3],[4,5]]
]
var o2 = JSON.parse(JSON.stringify(o1))
o2[0] = 2
o2[1][2] = [6,7]
console.log(o1[0]) //1
console.log(o1[1]) //[1,[2,3],[4,5]]

办法二:手撕

   // 定义检测数据类型的性能函数
   function checkedType(target) {return Object.prototype.toString.call(target).slice(8, -1)
   }
   // 实现深度克隆 --- 对象 / 数组
   function clone(target) {
     // 判断拷贝的数据类型
     // 初始化变量 result 成为最终克隆的数据
     let result, targetType = checkedType(target)
     if (targetType === 'object') {result = {}
     } else if (targetType === 'Array') {result = []
     } else {return target}
     // 遍历指标数据
     for (let i in target) {
       // 获取遍历数据结构的每一项值。let value = target[i]
       // 判断指标构造里的每一值是否存在对象 / 数组
       if (checkedType(value) === 'Object' ||
         checkedType(value) === 'Array') { // 对象 / 数组里嵌套了对象 / 数组
         // 持续遍历获取到 value 值
         result[i] = clone(value)
       } else { 
        // 获取到 value 值是根本的数据类型或者是函数。result[i] = value;
       }
     }
     return result
   }

   // 定义检测数据类型的性能函数
   function checkedType(target) {return Object.prototype.toString.call(target).slice(8, -1)
   }
   // 实现深度克隆 --- 对象 / 数组
   function clone(target) {
     // 判断拷贝的数据类型
     // 初始化变量 result 成为最终克隆的数据
     let result, targetType = checkedType(target)
     if (targetType === 'object') {result = {}
     } else if (targetType === 'Array') {result = []
     } else {return target}
     // 遍历指标数据
     for (let i in target) {
       // 获取遍历数据结构的每一项值。let value = target[i]
       // 判断指标构造里的每一值是否存在对象 / 数组
       if (checkedType(value) === 'Object' ||
         checkedType(value) === 'Array') { 
          // 对象 / 数组里嵌套了对象 / 数组
          // 持续遍历获取到 value 值
         result[i] = clone(value)
       } else { 
         // 获取到 value 值是根本的数据类型或者是函数。result[i] = value;
       }
     }
     return result
   }
退出移动版