美文网首页
浅拷贝和深拷贝

浅拷贝和深拷贝

作者: isSunny | 来源:发表于2019-07-11 17:10 被阅读0次

今天来讨论一下javascript中的浅拷贝和深拷贝。

首先我们先来看一下两个问题:

1.什么叫浅拷贝和深拷贝?

浅拷贝:将原对象的自身属性复制给新对象,如果原对象的属性是基本类型则直接进行值赋值,如果是引用类型则进行引用赋值,也就是说只进行一层赋值。

深拷贝:将原对象的自身属性复制给新对象,如果原对象的属性是基本类型则直接进行值赋值,如果是引用类型则复制这个引用类型,使得目标对象拥有一个引用类型且和这个源属性一模一样,而非是一个指针。

2.什么情况下浅拷贝、深拷贝?
由上面对两种拷贝的理解,很容易看出来,只有在对象里嵌套对象的情况下,才会根据需求讨论,我们要深拷贝还是浅拷贝。

接下来我们先了解一下js的基本类型和引用类型,有助于我们理解浅拷贝和深拷贝。

1.基本类型的变量和值是存在栈区的,如var a=1;var a = 2;如下图:


image.png

基本类型在赋值操作后,互相不影响。举个🌰

var a = 1;
var b = a;
a++;
console.log(a);//2
console.log(b);//1

2.引用数据类型:名存在栈内存,值存在堆内存,栈内存会提供一个指针指向堆内存中的值。如下图
var a = {};var b={}


image.png

所以赋值后,两个变量都保存在同一个对象地址,则两个变量指向同一个对象,所以改变任何一个变量都会受到影响。
举个🌰:

var a = {name:'li'};
var b = a;
console.log(a.name);//li
console.log(b.name);//li
a.name = 'zhang';
console.log(a.name);//zhang
console.log(b.name);//zhang
image.png

当a.name改变了,由于a与b指向的是同一个地址,所以自然b也受了影响。(另外引用赋值不是浅拷贝!! 引用赋值仅仅只是赋值个指针,两个变量都指向同一堆内存,而浅拷贝是使两个变量分别指向不同的堆内存)。


image.png
深拷贝和浅拷贝的区别:浅拷贝只是复制对象的第一层属性,而深拷贝可以对对象的属性进行递归复制。
浅拷贝:

1.for...in (只复制了对象的第一层,而对象内的对象是不同的引用,指向同一个内存空间,新的对象嵌套的对象改变,新的对象嵌套的对象也会改变)

var a = {name:"li",hobby:["eat","song","newthings"]};
        var b = {};
        for(var val in a){
            b[val] = a[val];
        }
        console.log(b);// {name:"li",hobby:["zhang","song","newthings"]};

       b.hobby[0] = "zhang";
       b.name = "chen";     
       console.log(a);  //{name:"li",hobby:["zhang","song","newthings"]};
       console.log(b);   //{name:"chen",hobby:["zhang","song","newthings"]};

2.数组 slice和concat
3.es6 扩展运算符...

深拷贝:

1.JSON.parse (JSON 并不支持函数类型的数据,所以对象中如果有函数类型不支持)

var obj= {c:1,d:[1,2,3,4,5]}
       var objNew = JSON.parse(JSON.stringify(obj));
       console.log(objNew);//{c:1,d:[1,2,3,4,5]}
       objNew.d.push(6);
       console.log(obj);//{c:1,d:[1,2,3,4,5]}
       console.log(objNew);//{c:1,d:[1,2,3,4,5,6]}

2.递归拷贝

 function deepClone(obj){
        //=>过滤特殊情况
        if(obj===null) return null;
        if(typeof obj !=='object') return obj;
        if (obj instanceof RegExp) return new RegExp(obj);
        if (obj instanceof Date) return new Date(obj);

        //判断是数组还是对象,不直接创建空对象目的:克隆的结果和之前保持相同的所属类
        let newObj = Array.isArray(obj)?[]:new obj.constructor;
        for(let key in obj){
            //如果是原型上的属性,不拷贝
            if(obj.hasOwnProperty(key)){
                newObj[key]=deepClone(obj[key]);
            }
        }
        return newObj;
        
    }
       //对象
       var obj= {c:1,d:[1,2,3,4,5]};
       var obj2 = deepClone(obj);
       console.log(obj2);////{c:1,d:[1,2,3,4,5]}
       obj.d.push(6);
       console.log(obj);//{c:1,d:[1,2,3,4,5,6]}
       console.log(obj2);//{c:1,d:[1,2,3,4,5]}
    
       var arr = [1,2,3,[1,2,4]];
        //数组
       var newArr = deepClone(arr);
       newArr[3].push(5);
       console.log(arr);//[1,2,3,[1,2,4]];
       console.log(newArr);//[1,2,3,[1,2,4,5]];

这里说一下Object.assign(),查阅了不同的资料,有把它归为浅拷贝的,也有把它归为深拷贝的,最开始也一脸懵,这里只能说如果拷贝的对象是非嵌套对象,可以说是深拷贝,如果对象中出现嵌套情况,那么它对被嵌套对象的行为就成了普通的浅拷贝了。也就是深拷贝一级对象,后面嵌套的属于浅拷贝,感觉和for..in一样。。。

3.jquery里的extend方法
$.extend( [deep ], {}, a, b )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
{}:将合并结果保存到新对象,这样原对象将不会发生改变
a:第一个合并的对象
b:第二个合并的对象

哦了~~~

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

  • JavaScript的深拷贝和浅拷贝

    原文 博客原文 大纲 前言1、对深拷贝和浅拷贝的初步认识2、深拷贝和浅拷贝的区别3、浅拷贝存在的缺陷4、深拷贝的实...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

网友评论

      本文标题:浅拷贝和深拷贝

      本文链接:https://www.haomeiwen.com/subject/jpvrkctx.html