基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6)
引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象,等等)
关于Symbol:https://blog.csdn.net/weixin_34354945/article/details/91460921
JS里的基本数据类型定义和C#里面的值类型差不多(String在c#里是引用类型),引用数据类型也是。
继续看了下,他们的存储方式也差不多,基本数据类型存储在栈上面,引用数据类型则是具体的值存在堆里面,指向堆里具体值的引用地址保存在栈上。
第一句先定义了对象a,第二句 var c = a 其实只是把a的引用地址复制了一份拿给了c,对于第三句修改c的name为其他值后,a的name也发生了变化,则是因为修改c的name属性时,是根据引用地址去堆里修改的。当a根据相同的引用地址去访问时这个对象时,拿到对象自然也就变掉了。
这里还要了解一个知识点:浅拷贝和深拷贝
浅拷贝:
浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,就无效了,也就是说只能拷贝一层。
这里用了Object.assign进行浅拷贝,类似的浅拷贝方法还有 扩展运算符 … 、 Array.prototype.slice()、 Array.prototype.concat()
关于扩展运算符:http://www.fly63.com/article/detial/2516
深拷贝:
深拷贝复制变量值,对于引用数据,则递归至基本类型后,再复制。
深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象
let obj = {
name: 'Michael',
age: 18,
others: {
hobbies: ['basketball', 'gambling'],
team: 'Bulls',
},
};
let obj1 = deepClone(obj);
obj1.age = 19;
obj1.others.team = 'test';
console.log('obj', obj);
console.log('obj1', obj1);
// 递归实现深拷贝
function deepClone(obj) {
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Date) return new Date(obj);
if (obj === null || typeof obj !== 'object') return obj //如果不是引用类型则直接返回
let newObj = new obj.constructor(); //如果obj是数组,newObj=[];如果obj是对象,newObj={}
for (let key in obj) {
if (obj.hasOwnProperty(key)) { //是否是自身的对象
newObj[key] = deepClone(obj[key]) //赋值
}
}
return newObj
}