年前在重写淘宝旺铺里的会员卡脚本的时候,无意中发现了一个有趣的事情。代码类似:

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);
}

扩展阅读:



共有24 条评论

  1. 1. 头像 chencheng

    顶,哈哈

  2. 2. 头像 macji

    看到加粗部分,就豁然开朗了。

  3. 3. 头像 蚂蚁线

    想不到啊!

  4. 4. 头像 kingmax

    看来博主的javascript基本功还不行。。。

  5. 5. 头像 digibread

    非常实用,有个问题请教:
    is[c] = (function(type){
    …… }
    })(c);
    有时会看到这样的结构,请问这是什么语法结构?我手头上的参考书没有这方面的介绍,所以这部分的代码读不懂。能否给个这方面的参考连接?谢谢

  6. 6. 头像 rainoxu

    var associative_array = [];
    associative_array[“raino”]=”rainoxu”;
    alert(associative_array [“raino”]==”rainoxu”)
    alert(associative_array.length)

    使用是可以的,但是长度为0,好像在某本书上看到过这个例子,虽然有点不同,可惜那本书上没有解释,但是如果碰到这种情况,为了避免误会的话,还是用对象更安全,至少不会出错了~~

  7. 7. 头像 怿飞

    @igibread 可以简化成:
    var a =function(type){
    ……
    };
    is[c] = a(c);

  8. 8. 头像 vampire

    前面的框都见过 最后那个框确实很有想法 你很有才
    那个for循环的用法很有意思 就是可读性差了点 呵呵

    刚刚留言的时候你博客突然变得很慢 然后就乱码了。。。

  9. 9. 头像 kyan

    associative_array[“one”] = “1”;
    associative_array[“two”] = “2”;associative_array[“three”] = “3”;

  10. 10. 头像 kyan

    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”;

  11. 11. 头像 脚本爱好者

    其实开始声明为什么类型不重要 ,关键是当什么类型去使用。

    同样, 你要是将数组赋值为一个字符串,那么他就是一个字符串。
    比如:
    var arr = [];
    arr = “asdasd”;
    alert(arr.length)
    弹出结果为6

  12. 12. 头像 擎天

    alert(associative_array.constructor == Array);

  13. 13. 头像 亚洲色图

    学习 技术不懂 呵呵·

  14. 14. 头像 琳琳的小狗

    啊哈,又一次看到“数组检测”。前一阵儿刚俺也发了篇文章介绍这个方法,不同的是,也把原理翻译过来了,详情可以参考:
    《Javascript数组类型检测:编写更强壮的isArray函数》
    http://scriptfans.javaeye.com/blog/318821

  15. 15. 头像 琳琳的小狗

    顺便,to digibread:
    你看到的这个东西,叫做“自执行函数”,属于js中比较常见的模式之一,可以用来划分命名空间等等,在这里的用途,主要是因为需要修正闭包共享变量的问题,要是不这么写,你会发现六个type最终都会变成“Object”:)

  16. 16. 头像 lonqi

    学习了,刚开始的时候倒是没有发现问题所在,仔细一看原来是键值为非数值字符了。。

  17. 17. 头像 mAmimoluo

    关于正确判断数组的方法的首创者是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

  18. 18. 头像 diyism

    javascript要是像php数组那样多好, 支持number索引, 也支持character索引, 免得总是用object来模仿数组了, 我觉得描述这个世界最方便的是treemap, 而不是object,
    treemap类型:
    python里是dictionary,
    java中是treemap/hashmap用起来很不方便(很多put),
    ruby中是hash(键可以是数字,字串或其它),
    php中是array,
    js里是object(用方括号当数组).

  19. 19. 头像 虫虫舞

    可以向您请教一下,您在文章里面的代码部分写在方框里的效果是怎样实现的吗?

  20. 20. 头像 KingFo

    恩 如果在AS中 Array 可以当作字典或者Map用
    如第一部分形式类似
    于是 在AS中比较猥琐的方法就是借用负数快速倒序排列
    如a[-1]
    当然 length==0

    嘿嘿 我又来八AS了

  21. 21. 头像 KingFo

    厄 竟然重复了一条。。。 BZ帮忙删一个吧。。。。

  22. 22. 头像 dongyuwei

    The Miller Device方法判断是否是数组,个人感觉没有以duck type的方式好。

  23. 23. 头像 jianxianxia

    如果是associative_array[‘0’] = ‘0’;
    associative_array[‘1’] = ‘1’;
    associative_array[‘2’] = ‘2’;
    alert(associative_array.length);弹出数组长度为3,这个又怎么解释呢,同样数组的下标为字符型

  24. 24. 头像 denis

    不错!

发表评论

(必填)

(必填,会为您保密)

评论仅支持“a、abbr、strong、em、blockquote、code”几个简单的标签