天行健、君子以自强不息;地势坤、君子以厚德载物!

关于我

zhenn 前端工程师,淘宝 北京!这里仅仅记录我的技术生活以及成长历程,如果有兴趣和我交流,猛击以下链接即可。
follow zhenn in TC Microblog
follow zhenn in SinaTwitter

object数据存储的无序性

object作为javascript的一种数据存储格式,采用哈希表的存取方式,即一个key对应唯一的值,这样的特性,有时候给开发带来很大的便利,比如当我们需要获得一系列不能重复的数字时,可以做如下处理:

var randomOne = function(){
	var i = 0 , obj = {};
	while(i < 6){
		var num = Math.ceil(10 * Math.random());
		if(obj[num]) continue;
		obj[num] = num;
		i ++;
	}
	return obj;
}
var o = randomOne();
for(var i in o){
	alert(o[i]);
}

 产生的随机数,分别作为key和value存入对象obj中,这样新产生的随机数在存入对象之前,只需先点对点的查找此数在对象中是否有相应的键值对,就可以确保数字的唯一性,而这样往往是比在数组中检索数据要快的多。

这一切看上去很完美,既满足了需求,又提高了性能,而事实上,一朵看上去很美丽的花往往是有毒的,一不小心就可以致人于死地。同样的,使用object存储数据给我们带来便捷的同时,也有一定的风险,正如你看到的文章标题,object数据存储时没有顺序的,当业务的需求对数据的顺序有严格要求的时候,这恰恰就是致你于死地的那滴毒液。

为了给上述的观点提供足够的佐证,请分别在webkit浏览器和非webkit浏览器中执行randomOne,横向对比两者的运算结果,就会发现在webkit中,遍历对象,输出数据的顺序是从小到大,而在非webkit中,则是按照存贮的先后顺序逐个输出。在这一点上,webkit事实上是把带有可转为number类型的key序列当做数组来处理的,以下更有说服力的代码:

var o = {};
o['s'] = '先存储的数据';
o[1] = '后存储的数据';
for(var i in o){
	alert(o[i])
}

webkit中的结果:'后存储的数据' -> '先存储的数据',非webkit中的结果:'先存储的数据' -> '后存储的数据'。

我想以上足够证明本文的观点了,下面的demo是在项目中遇到的应用场景,即随机产生一注双色球选号。

项目需求:

1,红球选号范围01-33,选号不能重复

2,篮球选号范围01-16

实际上,在webkit浏览器中,严重违背了项目需求,bug严重程度应该是A级,因为这影响了此功能的可用性,导致用户无法购买彩票。

所以,在对有数据顺序有要求的场景下,应该避免使用object来存取数据,尽量用array来替代,尽管这样会在一定程度上有损前端性能,但和破坏功能可用性比起来,还是不值一提的。

posted on 2011-02-27 21:20  zhenn  阅读(2689)  评论(10编辑  收藏  举报

导航