参考资料
https://juejin.im/post/59ac1c4ef265da248e75892b
看完上面的参考资料后你会发现, js有2大类型数据基础数据类型(boolean,undefined,null,string,number)及引用类型(object)
基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的,例如:
var str = 'abc'
str[1] = 'f'; // f, 只是返回了一个新字符,
console.log(str); // abc,
参考资料中:复制代码这一点其实开始我是比较迷惑的,总是感觉 js 是一个灵活的语言,任何值应该都是可变的,真是图样图森破,我们通常情况下都是对一个变量重新赋值,而不是改变基本数据类型的值。就如上述引用所说的那样,在 js 中没有方法是可以改变布尔值和数字的。倒是有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据。
var p1 = {a: 1}
var p2 = {a: 2}
p1 === p2; // false,因为指向的堆栈内存地址不同不是同一个
var obj = {a: 1}
var p1 = obj;
var p2 = obj;
p1 === p2; // true,因为他们指向同一个内存地址
p1.b = 2;
console.log(p2.b); // 2 因为指向同一内存地址,所以p2也会受影响
综上所述,并不是真正的浅拷贝,只是引用而已,浅拷贝和"="赋值还是有区别的。
// 此处内容为参考资料的内容
// 浅拷贝与赋值的区别
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,["二","三"],["四","五"]],
//};
- obj1:原始数据
- obj2:赋值操作得到
- obj3:浅拷贝得到
建议还是看参考资料吧。实在是太详细太明白了。
总结下:
类型 | 和原数据是否指向同一对象 | 第一层数据为基本数据类型 | 原数据中包含子对象 |
---|---|---|---|
赋值 | 是 | 改变会使原数据一同改变 | 改变会使原数据一同改变 |
浅拷贝 | 否 | 改变不会使原数据一同改变 | 改变会使原数据一同改变 |
深拷贝 | 否 | 改变不会使原数据一同改变 | 改变不会使原数据一同改变 |
我们在写代码的时候遇到的困难多是如何写出深拷贝,及复制一个对象,对该对象修改不会影响原始对象,最简单的方法就是: var newObj = JSON.parse(JSON.stringify(obj))