年前在重写淘宝旺铺里的会员卡脚本的时候,无意中发现了一个有趣的事情。代码类似:
var associative_array = new Array();
associative_array["one"] = "1";
associative_array["two"] = "2";
associative_array["three"] = "3";
if(associative_array.length > 0) {
// to do
}
会发现 associative_array.length 始终等于 0,当时有点迷惑,后来才知道这就像大家认为 IE 中支持 CSS 属性 display:inline-block 一样,纯属巧合和误解。
实际上(引自《JavaScript “Associative Arrays” Considered Harmful》):
JavaScript arrays (which are meant to be numeric) are often used to hold key/value pairs. This is bad practice. Object should be used instead.
//大意:数组只支持数字的,键值对应使用于对象上。
- There is no way to specify string keys in an array constructor. //在数组构造函数中无法定义字符串键值
- There is no way to specify string keys in an array literal. //在数组字面量中无法定义字符串键值
- Array.length does not count them as items. // Array.length 不会计算字符串键值
进一步窥探数组:
1、数组可以根据所赋的值自动调整大小
var ar = [];
ar[2] = 1;
alert(ar.length)
发现这个数组的长度为 3,就像一个经过初始化的数组一样。所有没有赋值的数组对象,都将被定义为 undefined 。
扩展阅读:
2、可使用 “The Miller Device” 方法来判断是否是数组
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
“The Miller Device” 的妙用不仅仅在于判断数组:
var is = {
types : ["Array","RegExp","Date","Number","String","Object"]
};
for(var i=0,c;c=is.types[i++];){
is[c] = (function(type){
return function(obj){
return Object.prototype.toString.call(obj) == “[object "+type+"]“;
}
})(c);
}
扩展阅读:
witter:
共有23 条评论
顶,哈哈
看到加粗部分,就豁然开朗了。
想不到啊!
看来博主的javascript基本功还不行。。。
非常实用,有个问题请教:
is[c] = (function(type){
…… }
})(c);
有时会看到这样的结构,请问这是什么语法结构?我手头上的参考书没有这方面的介绍,所以这部分的代码读不懂。能否给个这方面的参考连接?谢谢
var associative_array = [];
associative_array["raino"]=”rainoxu”;
alert(associative_array ["raino"]==”rainoxu”)
alert(associative_array.length)
使用是可以的,但是长度为0,好像在某本书上看到过这个例子,虽然有点不同,可惜那本书上没有解释,但是如果碰到这种情况,为了避免误会的话,还是用对象更安全,至少不会出错了~~
@igibread 可以简化成:
var a =function(type){
……
};
is[c] = a(c);
前面的框都见过 最后那个框确实很有想法 你很有才
那个for循环的用法很有意思 就是可读性差了点 呵呵
刚刚留言的时候你博客突然变得很慢 然后就乱码了。。。
associative_array["one"] = “1″;
associative_array["two"] = “2″;associative_array["three"] = “3″;
associative_array["one"] = “1″;
associative_array["two"] = “2″;
associative_array["three"] = “3″;
这样的写法是为数组associative_array增加来三个属性而已,和长度无关。等同写法:associative_array.one= “1″;
associative_array.two= “2″;
associative_array.three= “3″;
其实开始声明为什么类型不重要 ,关键是当什么类型去使用。
同样, 你要是将数组赋值为一个字符串,那么他就是一个字符串。
比如:
var arr = [];
arr = “asdasd”;
alert(arr.length)
弹出结果为6
alert(associative_array.constructor == Array);
学习 技术不懂 呵呵·
啊哈,又一次看到“数组检测”。前一阵儿刚俺也发了篇文章介绍这个方法,不同的是,也把原理翻译过来了,详情可以参考:
《Javascript数组类型检测:编写更强壮的isArray函数》
http://scriptfans.javaeye.com/blog/318821
顺便,to digibread:
你看到的这个东西,叫做“自执行函数”,属于js中比较常见的模式之一,可以用来划分命名空间等等,在这里的用途,主要是因为需要修正闭包共享变量的问题,要是不这么写,你会发现六个type最终都会变成“Object”:)
学习了,刚开始的时候倒是没有发现问题所在,仔细一看原来是键值为非数值字符了。。
关于正确判断数组的方法的首创者是prototype.js的维护着kangax提出的。
下面给出一种通用判断对象类型的方法:
var is =
{
types : ["Array", "Boolean", "Date", "Number", "Object", "RegExp", "String", "Window", "HTMLDocument"]
}
;
for(var i = 0, c; c = is.types[i ++ ]; )
{
is[c] = (function(type)
{
return function(obj)
{
return Object.prototype.toString.call(obj) == “[object " + type + "]“;
}
}
)(c);
}
alert(is.Array([])); // true
alert(is.Date(new Date)); // true
alert(is.RegExp(/reg/ig)); // true
关于具体的探讨请参考我的博客:http://hi.baidu.com/mimimo/blog/item/2240974580104b3887947387.html
javascript要是像php数组那样多好, 支持number索引, 也支持character索引, 免得总是用object来模仿数组了, 我觉得描述这个世界最方便的是treemap, 而不是object,
treemap类型:
python里是dictionary,
java中是treemap/hashmap用起来很不方便(很多put),
ruby中是hash(键可以是数字,字串或其它),
php中是array,
js里是object(用方括号当数组).
可以向您请教一下,您在文章里面的代码部分写在方框里的效果是怎样实现的吗?
恩 如果在AS中 Array 可以当作字典或者Map用
如第一部分形式类似
于是 在AS中比较猥琐的方法就是借用负数快速倒序排列
如a[-1]
当然 length==0
嘿嘿 我又来八AS了
厄 竟然重复了一条。。。 BZ帮忙删一个吧。。。。
The Miller Device方法判断是否是数组,个人感觉没有以duck type的方式好。
如果是associative_array['0'] = ‘0′;
associative_array['1'] = ‘1′;
associative_array['2'] = ‘2′;
alert(associative_array.length);弹出数组长度为3,这个又怎么解释呢,同样数组的下标为字符型