首先要掌握基本数据类型和引用数据类型及其存储位置,栈和堆的概念
赋值
我的理解,将一个变量的值赋值给另一个变量。使用的是等号。
例如:
- var a = 3; // 将数值3赋值给了变量a
- var b = a; // 将变量a的值赋值给变量b
- var arr1 = [1,2,3]; var arr2 = arr1; // 将数组arr1赋值给arr2,但是赋的是地址
总结:当修改其中一个变量时,基本数据类型互不影响,引用数据类型会互相影响因为是共用同一内存
因此,也有了浅拷贝和深拷贝的概念。
浅拷贝
浅拷贝不光光是只有赋值就可以实现,数组中有些方法就是浅拷贝(slice(),concat(),map(),filter(),reduce())、Object.assign()、展开运算符(…)等等。
接下来,展开讲一下:
var list1 = [1,2,3,4];
var listCopy1 = list1;
listCopy1.push(9);
console.log(list1,listCopy1); // [1,2,3,4,9],[1,2,3,4,9]
var list2 = [1,2,3,4];
var listCopy2 = [].concat(list2); // 或者ist.slice()或者Array.from(list)或者[..list]
listCopy2.push(9);
console.log(list2,listCopy2); // [1,2,3,4],[1,2,3,4,9]
/* 没有引起list变化,以为concat等等就是深拷贝了?这是错的*/
var list = [{name:'tom'},{age: 12}];
var listCopy = [...list];
listCopy[0].name = 'Alei';
console.log(list,listCopy); // [{name:'Alei'},{age: 12}],[{name:'Alei'},{age: 12}]
/* 数组中是对象时 就可以看到listCopy变了后list也变了,
所以不能说明concat()等等方法就是深拷贝。
说明一个问题深拷贝不是看什么方法,还得看引用类型是否进行了深拷贝,既然不是,那需要我们去实现深拷贝。*/
// 这里如何实现深拷贝 使用了JSON,但是有缺点即有些类型是不支持的 具体看JSON
var list4 = [{name:'tom'},{age: 12}];
var listCopy4 = JSON.parse(JSON.stringify(list4));
listCopy4[0].name = 'Alei';
console.log(list4,listCopy4); // [{name:'tom'},{age: 12}],[{name:'Alei'},{age: 12}]`
总结:浅拷贝就是进行拷贝一个新对象时,如果是原来对象属性值是基本数据类型,拷贝的就是基本数据类型的值,修改新对象属不会影响原对象的。如果原来对象属性值是引用数据类型,拷贝的是引用数据类型的地址,修改新对象时会影响原对象的。
PS:看到这里会不会觉得,这浅拷贝不和赋值一样么?基本数据类型不会影响,因为拷的都是值,而
引用数据类型修改就会影响,因为拷的都是值。解答:(我的理解,不保证准确)我认为赋值是浅拷贝的一种,浅拷贝是有很多种方法可以实现的。重点就是拷贝,拷了一个新的,赋值只是把自己赋值给新的而已,可以理解成拷贝而已。大概是这样把吧。。。
深拷贝
刚刚提到了一种方法可以实现,那就是JSON,看到网上还有递归函数也可以实现,还有很多吧。。网上可以搜到。
我认为,对于深拷贝就是弥补了浅拷贝的不足,使得引用数据类型可以实现真真的拷贝,不只是复制了地址,是连值也复制了的,是完完整整的拷贝了一个新的对象。因此,修改新对象时不会改变原对象。
这块还有很多内容要掌握~~仍需要学习~