Javascript 的数组Array,既是一个数组,也是一个字典(Dictionary)。先举例看看数组的用法




Javascript 的数组Array,既是一个数组,也是一个字典(Dictionary)。先举例看看数组的用法。 



代码如下:


var a = new Array();  
  
 a[0] = "Acer";  
  
 a[1] = "Dell";  
  
 for (var i = 0; i < a.length; i++) {  
  
 alert(a[i]);  
  
 }



下面再看一下字典的用法。 


代码如下:


var computer_price = new Array();  
  
 computer_price["Acer"] = 500;  
  
 computer_price["Dell"] = 600;  
  
 alert(computer_price["Acer"]);


我们甚至可以同样象上面那样遍历这个数组(字典) 


代码如下:


for (var i in computer_price) {  
  
 alert(i + ": " + computer_price[i]);  
  
 }


这里的 i 即为字典的每个键值。输出结果为: 

Acer: 500  
 
 Dell: 600



另外 computer_price 是一个字典对象,而它的每个键值就是一个属性。也就是说 Acer 是 computer_price 的一个属性。我们可以这样使用它: 


computer_price.Acer


再来看一下字典和数组的简化声明方式。 

var array = [1, 2, 3]; // 数组  
 
 var array2 = { "Acer": 500, "Dell": 600 }; // 字典  
 
 alert(array2.Acer); // 500

这样对字典的声明是和前面的一样的。在我们的例子中,Acer又是键值,也可是作为字典对象的属性了。 



下面再来看看如何对一个对象的属性进行遍历。我们可以用 for in 来遍历对象的属性。 


代码如下:



function Computer(brand, price) {  
  
 this.brand = brand;  
  
 this.price = price;  
  
 }  
  
 var mycomputer = new Computer("Acer", 500);  
  
 for (var prop in mycomputer) {  
  
 alert("computer[" + prop + "]=" + mycomputer[prop]);  
  
 }


上面的代码中,Computer有两个属性,brand 和 price.所以输出结果为: 


computer[brand]=Acer  
 
 computer[price]=500


上面的这种用法可以用来查看一个对象都有哪些属性。当你已经知道Computer对象有一个brand属性时,就可以用 

mycomputer.brand


或 mycomputer[brand] 


来获取属性值了。 


总结:Javascript中的数组也可以用来做字典。字典的键值也是字典对象的属性。对一个对象的属性进行遍历时,可以用for in。 



数组遍历与属性 


虽然在 JavaScript 中数组是是对象,但是没有好的理由去使用 for in 循环 遍历数组。 


相反,有一些好的理由不去使用 for in 遍历数组。 


注意: JavaScript 中数组不是 关联数组。 


JavaScript 中只有对象 来管理键值的对应关系。但是关联数组是保持顺序的,而对象不是。 


由于 for in 循环会枚举原型链上的所有属性,唯一过滤这些属性的方式是使用hasOwnProperty 函数, 


因此会比普通的 for 循环慢上好多倍。 


遍历 


为了达到遍历数组的最佳性能,推荐使用经典的 for 循环。 


代码如下:



var list = [1, 2, 3, 4, 5, ...... 100000000];  
  
 for(var i = 0, l = list.length; i < l; i++) {  
  
 console.log(list[i]);  
  
 }


上面代码有一个处理,就是通过 l = list.length 来缓存数组的长度。 


虽然 length 是数组的一个属性,但是在每次循环中访问它还是有性能开销。 


可能最新的 JavaScript 引擎在这点上做了优化,但是我们没法保证自己的代码是否运行在这些最近的引擎之上。 


实际上,不使用缓存数组长度的方式比缓存版本要慢很多。 


length 属性 


length 属性的 getter 方式会简单的返回数组的长度,而 setter 方式会截断数组。 


代码如下:


var foo = [1, 2, 3, 4, 5, 6];  
  
 foo.length = 3;  
  
 foo; // [1, 2, 3]  
  
 foo.length = 6;  
  
 foo; // [1, 2, 3]


译者注: 


在 Firebug 中查看此时 foo 的值是: [1, 2, 3, undefined, undefined, undefined] 


但是这个结果并不准确,如果你在 Chrome 的控制台查看 foo 的结果,你会发现是这样的: [1, 2, 3] 


因为在 JavaScript 中 undefined 是一个变量,注意是变量不是关键字,因此上面两个结果的意义是完全不相同的。 


// 译者注:为了验证,我们来执行下面代码,看序号 5 是否存在于 foo 中。 


5 in foo; // 不管在 Firebug 或者 Chrome 都返回 false 


foo[5] = undefined;



5 in foo; // 不管在 Firebug 或者 Chrome 都返回 true 


为 length 设置一个更小的值会截断数组,但是增大 length 属性值不会对数组产生影响。 


结论 


为了更好的性能,推荐使用普通的 for 循环并缓存数组的 length 属性。 


使用 for in 遍历数组被认为是不好的代码习惯并倾向于产生错误和导致性能问题。