一、ES6中扩展运算符

ES6中的扩展运算符(如果只是一层数组或者对象就是深拷贝,多层就是浅拷贝)

var obj = {
        name : "海绵宝宝",
        age: 18,
        sayHello (){
            console.log("比奇堡早上好");
        }
    }
    var newObj = {...obj}
    console.log("obj :",obj);
    console.log("newObj :",newObj);

运行结果

js深拷贝方法

对newObj进行修改,并不会改变obj的属性

    var obj = {
        name : "海绵宝宝",
        age: 18,
        sayHello (){
            console.log("比奇堡早上好");
        }
    }
    var newObj = {...obj}
    console.log("obj :",obj);
    console.log("newObj :",newObj);
    newObj.name = "派大星"
    console.log("对newObj进行修改后");
    console.log("obj :",obj);
    console.log("newObj :",newObj);

运行结果:

js深拷贝方法

扩展运算符可以实现深层次的拷贝,但是多层数组或者对象就实现不了深拷贝了

代码:

    var obj = {
        name:"海绵宝宝",
        age:20,
        bestFriend:{
            name:"派大星",
            age:21,
            hobby:"抓水母"
        }
    }
    var newObj = {...obj}
    console.log("obj :",obj);
    console.log("newObj :",newObj);
    newObj.bestFriend.hobby = "发呆"
    console.log("修改过后......");
    console.log("obj=>besFriend=>hobby :",obj.bestFriend.hobby); // 发呆
    console.log("newObj=>besFriend=>hobby : :",newObj.bestFriend.hobby); //发呆

二、JSON.parse( JSON.stringify ( 待拷贝对象 ) )

虽然是深拷贝,但是没有办法拷贝函数内部函数

代码:

    var obj = {
        name : "海绵宝宝",
        age: 18,
        sayHello (){
            console.log("比奇堡早上好");
        }
    }
    var newObj = JSON.parse(JSON.stringify(obj))
    console.log("obj :",obj);
    console.log("newObj :",newObj);

运行结果:(会发现新拷贝的newObj中并没有sayHello这个函数)

js深拷贝方法

对newObj进行修改:

    var obj = {
        name : "海绵宝宝",
        age: 18,
        sayHello (){
            console.log("比奇堡早上好");
        }
    }
    var newObj = JSON.parse(JSON.stringify(obj))
    console.log("obj :",obj);
    console.log("newObj :",newObj);
    newObj.name = "派大星"
    console.log("对newObj进行修改后");
    console.log("obj :",obj);
    console.log("newObj :",newObj);

运行结果:

js深拷贝方法

三、数组中的slice和concat方法

这两个数组的方法虽然可以实现单层深拷贝,对于多层是无效的

slice方法:

    var arr = [1,2,3,4]
    var newArr = arr.slice()
    console.log("arr:",arr);
    console.log("newArr",newArr);
    newArr.push(5)
    console.log("修改newArr后");
    console.log("arr:",arr);
    console.log("newArr",newArr);

运行结果:

js深拷贝方法

concat方法:

    var arr = [1,2,3,4]
    var newArr = [].concat(arr)
    console.log("arr:",arr);
    console.log("newArr",newArr);
    newArr.push(5)
    console.log("修改newArr后");
    console.log("arr:",arr);
    console.log("newArr",newArr);

运行结果:

js深拷贝方法

两种方法均不可以拷贝深层次的数组

代码:

    var arr = [1,2,3,4,[5,5,5,5]]
    var newArr = arr.slice()
    console.log("arr:",arr);
    console.log("newArr",newArr);
    newArr[4].push(6)
    console.log("修改newArr后");
    console.log("arr:",arr);
    console.log("newArr",newArr);

运行结果:

js深拷贝方法

四、jQuery 中的 $.extend (添加true就是深拷贝,不添加就是浅拷贝)

代码:

var obj = {
        name : "海绵宝宝",
        age: 18,
        sayHello (){
            console.log("比奇堡早上好");
        }
    }
    var newObj = {}
    $.extend(true,newObj,obj)
    console.log("obj:",obj);
    console.log("newObj:",newObj);
    newObj.name = "派大星"
    console.log("修改过后");
    console.log("obj:",obj);
    console.log("newObj:",newObj);

运行结果:

js深拷贝方法

五、手写递归

实现思路:

  1. 在函数内部定义一个变量,来存储拷贝出来的内容
  2. 首先判断传进来的参数是否是引用数据类型,不是引用数据类型返回参数(这里面用的是typeof判断)
  3. 接下来用instanceof判断是数组还是对象,并且将定义的变量赋值为空数组或者空对象
  4. 接下来对传进来的参数进行枚举,对枚举出来的属性进行判断递归

代码:

    function deepClone(obj) {
        if(typeof obj !=="object" || obj == null){
            return obj 
        }
        let res 
        if(obj instanceof Array){
            res = []
        }else{
            res = {}
        }
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                res[key] = deepClone(obj[key])
            }
        }
        return res
    }

发表回复