深拷贝与浅拷贝的区别

我们先复习一下 ECMAScript 中的数据类型
在这里插入图片描述

基本数据类型存放在栈中(String,Numble,Boolean,Null,Undefine)

存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。

基本数据类型值不可变

javascript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。对数字和布尔值来说显然如此 —— 改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来假改字符串中的字符。实际上,javascript 是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。

引用类型存放在堆中( Object )

引用类型(object)是存放在堆内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况开进行特定的分配,例如。

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};

在这里插入图片描述

1.浅拷贝(遍历赋值)

  var obj1 = {
    'name' : 'zhangsan',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],
};
var obj2 = obj1;


var obj3 = shallowCopy(obj1);
function shallowCopy(src) {
    var dst = {};
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop];
        }
    }
    return dst;
}
obj2.name = "lisi";
obj3.age = "20";
obj2.language[1] = ["二","三"];
obj3.language[2] = ["四","五"];
console.log(obj1);  
//obj1 = {
//    'name' : 'lisi',
//    'age' :  '18',
//    'language' : [1,["二","三"],["四","五"]],
//};
console.log(obj2);
//obj2 = {
//    'name' : 'lisi',
//    'age' :  '18',
//    'language' : [1,["二","三"],["四","五"]],
//};
console.log(obj3);
//obj3 = {
//    'name' : 'zhangsan',
//    'age' :  '20',
//    'language' : [1,["二","三"],["四","五"]],
//};
2.深拷贝

2.1 自定义函数遍历

var obj = {
x: 1,
y: {
    a: 0,
            b: true,
            c: [1, 2, 3, 5]
}
};
var obj2 = deepCopy(obj);
console.log(obj2);
// 深拷贝 - > 浅拷贝
    function getType(obj) {
            return Object.prototype.toString.call(obj).slice(8, -1);
    }
function deepCopy(obj) {
        var result, oClass = getType(obj); //获取数据类型
        if (oClass === "Object") { // 类型判断
                result = {};
            } else if (oClass === "Array") {
                    result = [];
            } else {
                        return obj; //值类型 不会执行下面的for - in 直接返回该值
            }
            for (var i in obj) {
                        var copy = obj[i]; // 获取对象的每一个值
                        if (getType(copy) === 'Object') {
                        result[i] = deepCopy(copy);
                        } else if (getType(copy) === 'Array') {
                                    result[i] = deepCopy(copy);
                                } else {
                                        result[i] = copy;
                                        }
                        }
                            return result;
        }

2.2 JSON.stringify 进行深拷贝

var obj = {
x: 1,
y: [1, 2, 3, 5]
}
// 使用JSON.parse 和 JSON.stringify 进行深拷贝
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.y[0] = 'aaa';
console.log(obj2);
console.log(obj);

**2.3 Object.create() 失效 浅拷贝 **

var obj = {
x: 1,
y: {
a: 0,
b: true,
c: [1, 2, 3, 5]
}
};
var obj2 = Object.create(obj);
console.log(obj2);

2.4 $.extend() 失效 浅拷贝

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
var obj = {
x: 1,
y: {
a: 0,
b: true,
c: [1, 2, 3, 5]
}
};
var obj2 = $.extend({}, obj);
console.log(obj2);
</script>

2.5 Object.create(Object.getPrototypeOf(obj)) 失效 浅拷贝
注意:
Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。

Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

// 写法一
const clone2 = Object.assign(
Object.create(Object.getPrototypeOf(obj)),
obj
);
// 写法二
const clone3 = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值