最近遇写 node.js 时到一个问题,把对象当赋值给数组成员时总是出错,比如下面的代码,

var Arr = new Array();
var Obj = new Object(); for(var i =0; i<5; i++ ){
Obj.a = i;
Arr[i] = Obj;
} for(var i in Arr ){
console.log( Arr[i].a );
}

输出是这样的:

4
4
4
4
4

但是不使用对象的时候是正常的,如下面的代码

var Arr = new Array();

for(var i =0; i<5; i++ ){
Arr[i] = i;
} for(var i in Arr ){
console.log(Arr[i]);
}

输出是这样的:

0
1
2
3
4

想了好长时间,后来想到可能是对象比较特殊,传了个指针过来,估计和 C++ 浅拷贝深拷贝那一套差不多。后来证明确实如此。把最开始的代码改成下面这样就正常了。

var Arr = new Array();

for(var i =0; i<5; i++ ){
function fun(){
var Obj = new Object();
Obj.a = i;
return Obj;
}
Arr[i] = fun();
} for(var i in Arr ){
console.log( Arr[i].a );
}

下来找了资料看了看,现在总结一下:

  1. 变量可以存放两种类型的值: 原始值 和 引用值
  2. 原始值代表原始数据类型的值,也叫基本数据类型,包括 Number、Stirng、Boolean、Null、Underfined。
  3. 引用值指的是复合数据类型的值,包括 Object(Array也是Object)、Function、Date、RegExp。

根据数据类型的的不同,有的变量存储在栈中,有的存储在堆中。

  • 原始变量类型及他们的值存储在栈中,当把一个原始变量传递给另一个原始变量时,是把一个一段栈空间的内容复制到另一段栈空间,这两个原始值互相不影响。

  • 引用值是把引用变量的名称存储在栈中,但是把其实际对象存在堆中,且存在一个指针有变量名指向存储在堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不通过方法,而是通过重新赋值 此时 相当于 重新开了一段内存 该值的原指针改变 ,则另外一个 值 不会随他的改变而改变。

 总结:

  Number、Stirng、Boolean、Null、Underfined这些基本数据类型,他们的值直接保存在栈中;

  Object、Function、Array、Date、RegExp这些引用类型,他们的引用变量储存在栈中,通过指针指向储存在堆中的实际对象

04-30 04:30