深拷贝与浅拷贝

一、问题背景

在刷一道比较简单的题目时,遇到一个容易忽略的问题,js对象的浅拷贝和深拷贝的问题,从而导致的输出结果不对;所以总结一下js中深拷贝和浅拷贝的问题。

二、浅拷贝
在javascript中数据类型有两种

基本数据类型:number,boolean,string,null,undefined;

该类型数据的赋值操作就是值的赋值,前后两者不相互影响

var num1 = 1;
var num2 = num1;
num2 = 3;
console.log(num1) // 1
console.log(num2) // 3

引用数据类型:object、array、function;

该类型数据的赋值操作拷贝的是内存地址,因此两者会互相影响

var obj = {
    name: 'test'
};
var obj1 = obj;
obj1.name = 'test1'
console.log(obj1.name) // test1
console.log(obj.name) // test1

因此浅拷贝只是简单的赋值,遍历对象的每个属性进行逐个拷贝,浅拷贝对于引用类型数据,会出错。
实现方式:

  • 遍历并复制
  • Object.assing()

三、深拷贝
深拷贝就是创建了一个新对象,并复制原对象,两者互不影响
实现方式:

  • 手动复制
  • 递归拷贝

js中数组实现深拷贝的方法:

  • for循环遍历,复制给新数组
  • concat连接数组
  • slice方法发挥一个新数组
  • ES6扩展运算符实现数组的深拷贝 […arr2] = arr1

刷题示例代码:

var kidsWithCandies = function(candies, extraCandies) {
    var maxarr = candies.concat()
    maxarr.sort(function(x,y) {
        return y-x
    })
    var max = maxarr[0]
    var len = candies.length
    var res = []
    for(var i=0;i<len;i++) {
        var addnum = candies[i] + extraCandies
        console.log(addnum, candies)
        if(addnum >= max) {
            res.push(true)
        }else {
            res.push(false)
        }
    }
    return res
};