敬业福还是抢不到~~还是继续写教程吧
js内存管理,往深了讲很复杂,这里只是浅显的介绍,帮助你理解js的基本类型和引用类型,以及它们拷贝问题,顺带着讲一下递归在内存的实现,帮助你了解递归了,以及闭包了的知识。讲的不对的地方还请指正,
1、栈(stack)和堆(heap)
stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。
2、基本类型和引用类型
基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。
5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。
引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。
当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
3.浅拷贝(赋给的是一个指针,并不是真正的值)
var o = {
name :"小花",
friend:['小明','小蓝']
}
function copy(o){
var c = {};
for(var i in o){
c[i] = o[i];
}
return c;
}
//上面的形式,我在介绍原型式继承的时候原型式继承也是一种浅拷贝,有兴趣的看我上一篇文章,继承和这个稍有不同,在这里不做叙述
var c1 = copy(o);
c1.name = "小黑";
c1.friend.push("小白");
var c2 = copy(o);
console.log(c2.name);//小花
console.log(c2.frined);//'小明','小蓝'小白
看一下它们的关系图就应该清楚了
3.深度拷贝
我们不希望,修改c1的值影响,影响c2,那就不能单纯的复制指针了,应该把对象的属性也复制一遍。上酸菜
var o = {
name :"小花",
friend:['小明','小蓝']
}
function copy(o,c){//c 拷贝 o 被拷贝的
var c = c || {};
for(var i in o){
if(typeof o[i] === 'object'){
c[i] = (o[i].constructor = 'Array')?[]:{};
copy(o[i],c[i]);
}else{
c[i] = o[i];
}
}
return c;
}
var c1 = copy(o);
o.friend.push("小黑");
console.log(c1.friend);//'小明','小蓝'
通过上面的例子,可以发现实现深度的复制,o对象和c1对象,修改属性值,已经没有了影响,它们现在的内存关系图是
通过上面的例子,都懂了吧
上面我们用到了递归,我们讲解一下它的原理,以及在内存情况
举一个栗子
var num = 5;
function start(num){
if(num>3){
start(--num);
}
alert(num);
}
start(num);//调用 3 3 4
why 为什么是3 3 4 呢,我们画一下内存图就明白
能看懂函数的递归,也就能明白函数的闭包的原理了,休息一下,过会讲解闭包的原理