js存储方式
- 基本数据类型,如:Undefined,Null,Boolean,Number,String 存储在栈中,因为这些数据小而且可预知。
var obj1={
a:1// a的属性被存到栈中[value:1,xxxx: ,yyyy: ],1属于基本类型,直接存储到了value里
}
- 引用数据类型,如:对象,数组,函数,这些类型大小不固定,所以存储在堆中,并把地址赋给某个变量的在栈中的value属性。
var obj2={
a:function(){
}// a的属性被存到栈中[value:函数在堆中的地址,xxxx: ,yyyy: ],函数是引用类型,地址存储到了value里
}
- 如果一个对象复制给另一个对象,修改其中一个会影响到另一个
var a={x:1}
var b=a;
b.x=2;
此时:a.x=2,不再等于1了
为什么这么存储
- 栈区:在低地址,连续,可申请的区域有限
- 堆区:在高地址,不连续,空闲的部分都可申请,比较大
- 一般情况下,是从低往高地址读取,所以栈区先读,效率就高
运行环境
- 由于js的存储方式决定,引用类型存在堆中,变量的属性存储在栈中的value里,所以当变量a赋给另一个变量b的时候,是把value里的地址给了b,当变量b运行的时候,b和a所处的环境不同,导致引用类型在运行的时候,会收到a或者b所在的环境的影响。
var obj1 = {
f1: function() { // 本函数被存到堆中,把地址给了f1
return this.aaa
},
aaa: 1
}
var f = obj1.f1; // 此时的f的value里的地址和obj1.f1的value里的地址是一样的
var aaa = 10;
var obj2 = {
f2: obj1.f1, // 此时的f2的value里的地址和obj1.f1的value里的地址是一样的
aaa: 2
}
// 函数只有一份,只是把地址给了三个变量f1、f2、f,他们对函数本体独立操作。
console.log('f: ', f()) // f调用函数的时候,f的环境里aaa=10;
console.log('f1: ', obj1.f1()) // f1调用函数的时候,f1的环境里aaa=1;
console.log('f2: ', obj2.f2()) // f2调用函数的时候,f2的环境里aaa=2;
网友评论