数据类型
JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。ES6新增的数据类型:Symbol,BigInt ,Set,Map。其中Set,Map都归为Object
-
栈:原始数据类型(Undefined、Null、Boolean、Number、String)
-
堆:引用数据类型(对象、数组和函数)
-
原始数据类型直接存储在栈中,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
-
引用数据类型存储在堆中,占据空间大、大小不固定。引用数据类型在栈中存储了指针,该指针指向堆中该实
体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
参考: 数据类型
赋值
let obj = {name:'zs'};
let obj2 = obj;//这种属于赋值,同一块内存,不同指针
浅拷贝
下面将一下三种浅拷贝。
需要创建一个新的对象
拷贝的值:如果属性是一般数据类型,拷贝的就是基本类型的值,如果属性是引用数据类型,那拷贝的就是内存地址
function shallowCopy(source) {
var newObj = {}
for (const key in source) {
// hasOwnProperty的作用是判断对象source的属性中是否存在key属性,不包括source原型链上的
if (source.hasOwnProperty(key)) {
newObj[key] = source[key]
}
}
return newObj
}
let obj = { a: 1, b: 4, c: [1, 2, 3], obj: { d: 5 } }
console.log(obj);//a=2,c=[1,2,3,4],d = 6
console.log(shallowCopy(obj));//a=1,c=[1,2,3,4],d = 6
obj.a = 2;
obj.c.push(4);
obj.obj.d = 6
第二种
let obj = {a:1,b:[1,23]}
let obj2 = Object.create(obj)
第三种,es7
let obj ={a:1,b:[1,23]}
let obj2 = {...obj }
深拷贝
拷贝的值:如果属性是引用数据类型,会开辟一块新内存(反正就是完全拷贝一份)
什么情况下使用深拷贝,当我们希望在改变新的数组(对象)的时候,不改变原数组(对象)
- 利用
JSON.stringify
对对象进行拷贝,不能拷贝对象中的函数
let obj = {
a: 1,
b: 4,
c: [1, 2, 3],
obj: { d: 5 },
fn: function () {
console.log(1);
}
}
let obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj);//obj.obj.d = 10,a=2,fn
obj.obj.d = 10
obj.a =2
console.log(obj2);//obj.obj.d = 5,a=1,无fn函数
- 利用递归
let obj = {
a: 1,
b: [1, 2, 3],
c_obj: { d: 5 },
fn: function () {
console.log(this.c_obj);
}
}
function deepCopy(obj) {
let newObj = Array.isArray(obj) ? [] : {}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
newObj[key] = deepCopy(obj[key])
} else {
newObj[key] = obj[key]
}
}
}
return newObj
}
let obj2 = deepCopy(obj)
console.log(obj);//a:2
console.log(obj2);//a:1
obj.a = 2
obj.c_obj.d = 6
obj.fn()//{d:6}
obj2.fn()//{d:5}