数据类型
- 基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6)
- 引用类型:Object、Array、Function
基本数据类型保存在栈内存,栈内存分别存储着变量的标识符以及变量的值
引用类型保存在堆内存中,栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当需要访问引用类型的值时,首先从栈中获取该对象的地址指针,然后再从堆内存中取得所需的数据
基本类型和引用类型的复制方式
- 基本类型的复制:复制了栈中的值给了新的变量
- 引用类型的复制:复制了栈中的存储地址(也可以叫堆内存的引用,这个地址指向堆内存的地址),即原来的变量和新变量指向了同一个东西
浅拷贝和深拷贝的区别
深浅拷贝都是针对引用类型。他们都会复制第一层的值,所谓第一层就是key所对应的value值是基本数据类型。到第二层的时候也就是引用类型(子对象),浅拷贝复制的是引用,深拷贝则会递归复制值。
浅拷贝
function clone(obj){
let newObj = Array.isArray(obj) ? [] : {};
for(const key in obj) {
// hasOwnProperty 可忽略继承过来的(构造函数原型上的)属性
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key]
}
}
return newObj;
}
function Father () {
this.name = 'F';
}
Father.prototype.age = 10;
const c = new Father();
const cloneC = clone(c);
console.log('c: ', c); // c: Father { name: "F", __proto__: { age: 10 }}
console.log('cloneC: ', cloneC); // cloneC: { name: "F" } ,过滤了原型对象上的age
深拷贝
function deepClone(obj){
let newObj = Array.isArray(obj) ? [] : {};
for(key in obj) {
// hasOwnProperty 可忽略继承过来的(构造函数原型上的)属性
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
newObj[key] = deepClone(obj[key])
} else {
newObj[key] = obj[key]
}
}
}
return newObj;
}
const o = {
b: 1,
c: {
d: 2,
}
}
const cloneO = deepClone(o)
cloneO.b = 3;
cloneO.c.d = 4;
console.log('o: ', o); // o: {b: 1, c: {d: 2}}
console.log('cloneO: ', cloneO); // // o: {b: 3, c: {d: 4}}