一.数据类型
数据分为基本数据类型和引用数据类型
基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)
引用数据类型(Object[Array属于Object])
基本数据类型的特点:直接存储在栈(stack)中的数据
引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
二.深拷贝与浅拷贝
1.浅拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
1.浅拷贝是按位拷贝对象,它会创建一个新对象,有着原始对象属性值的一份精确拷贝。
2.如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
2.深拷贝
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)
1.拷贝第一层级的对象属性或数组元素
2.递归拷贝所有层级的对象属性和数组元素
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
三.js实现深拷贝和浅拷贝
1.浅拷贝
<script>
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18,
color: ['pink', 'blue']
}
};
var o = {}
for (var k in obj) {
// k 是属性名 obj[k] 是属性值
o[k] = obj[k];
}
console.log(o);
o.msg.age = 20;
console.log(obj);
// Object.assign(o, obj) // 浅拷贝语法糖
// console.log(o);
// o.msg.age = 20;
// console.log(obj);
</script>
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,因此如果修改其中一个对象,另一个也会跟着改变。
2.深拷贝
<script>
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
// 用递归的方式完成深拷贝
// 封装函数
function deepCopy(newobj, oldobj) {
// 遍历oldobj的属性名
for (var k in oldobj) {
// 判断属性属于哪种数据类型
// 1.获取属性值 oldobj[k]
var item = oldobj[k];
// 2.判断是否属于数组(因为数组也属于对象,所以必须先判断数组)
if (item instanceof Array) {
newobj[k] = []; // (1)先给newobj添加一个属性k,同oldobj里的k
deepCopy(newobj[k], item) // (2)再用oldobj[k]赋值给newobj[k]
} else if (item instanceof Object) {
// 3.判断是否属于对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
// 4.属于简单数据类型
newobj[k] = item
}
}
}
deepCopy(o, obj)
console.log(o);
</script>
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会影响到原对象。