关于JS堆叠与拷贝
1、栈(stack)和堆(heap)
stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。
2、基本型别和引用型别
基本型别:存放在栈内存中的简单资料段,资料大小确定,内存空间大小可以分配。
5种基本资料型别有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。
引用型别:存放在堆内存中的物件,变数实际储存的是一个指标,这个指标指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。
当我们需要访问引用型别(如物件,阵列,函式等)的值时,首先从栈中获得该物件的地址指标,然后再从堆内存中取得所需的资料。
3、传值与传址
前面之所以要说明什么是内存中的堆、栈以及变数型别,实际上是为下文服务的,就是为了更好的理解什么是“浅拷贝”和“深拷贝”。
基本型别与引用型别最大的区别实际就是传值与传址的区别。
js物件的深拷贝
关于物件的深拷贝一直是大家津津乐道一个话题,本骚年通过研究(yuedu)发现还是很easy的。首推的方法简单有效,JSON.stringfy()和JSON.parse()即可搞定。但是这种简单粗暴的方法有其局限性。当值为undefined、function、symbol 会在转换过程中被忽略。。。所以,物件值有这三种的话用这种方法会导致属性丢失。
var syb = Symbol(\'obj\');
var person = {
name :\'tino\',
say: function(){
console.log(\'hi\');
},
ok: syb,
un: undefined
}
var copy = JSON.parse(JSON.stringify(person))
// copy
// {name: "tino"}
所以如果物件值中有这哥仨的话就要采用别的方法了,比如自己写个函式什么的搞定,比如这样。
function deepCopy(obj) {
var result = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === \'object\') {
result[key] = deepCopy(obj[key]); //递回复制
} else {
result[key] = obj[key];
}
}
}
return result;
}
还有一些Object.assgin(), 阵列的slice()这些,这些只深复制了基本型别资料型别,不是真正意义的深复制,当然,如果要复制的物件或者阵列都是简单资料型别,那就大胆用吧。
所谓方法,没有最优,只有最合适的,所以选择最合适的就ok啦。