楼兰之风...

致力于解放和提高软件开发生产力,欢迎访问 www.ewikisoft.com 填写您的邮件地址,订阅我们的精彩内容:

导航

JavaScript的sort函数报“缺少数字”错误的原因、分析与疑惑

  我们知道,js的数组具有一个sort方法,这个sort方法还可以传入一个特定形式的比较函数进行自定义排序,它的用法类似这样:

[5,4,9,2,7].sort(function(a,b){return(a-b);});

这个特定形式的自定义比较函数,要求有两个参数,通常情况下,函数的内容是两个参数本身或其属性的对比,该函数的返回值必须为负数、0和正数之一。另外sort函数会改变数组,而不是返回一个新的数组。

 

  最近我的一段js代码使用了js数组的自定义排序,在ie8和ff4下正常,然而在ie6和ie7下报“缺少数字”错误,经过研究发现,是自定义比较函数的返回值出现了NaN这个非数字造成的,这种情况下,ie6和ie7直接报错,而ie8和ff4不会报错,如下的代码可以可以重现这个问题:

    var arr = [
        {o:
3,toString:function(){return this.o}},
        {o:undefined,toString:
function(){return this.o}},
        {o:
4,toString:function(){return this.o}},
        {o:
1,toString:function(){return this.o}}
    ];
    arr.sort(
function(a,b){return a.o-b.o;});//使用元素的o属性进行比较
    
    debug.innerHTML
=arr;

由于数组arr中有一个元素的o属性没有定义,因此比较函数中会出现数字与undefined相减的情况,结果就是NaN,于是ie6和ie7报错了,截图如下:

 

 

  解决这个问题的办法,就是避免自定义比较函数返回非数字。但是ie8为什么不报错呢?难道ie8下传给sort函数的比较函数返回NaN不抱错吗?答案是肯定的,当比较函数的返回值为NaN的话,ie8不会报错,但是排序结果会发生一些不可预料的变化,上面同样的代码,在ie8下的结果是:

1,3,undefined,4

这个结果令我疑惑,如果把arr改成:

var arr = [
        {o:
3,toString:function(){return this.o}},
        {o:
6,toString:function(){return this.o}},
        {o:undefined,toString:
function(){return this.o}},
        {o:
4,toString:function(){return this.o}},
        {o:
1,toString:function(){return this.o}}
    ];

则排序后结果是:

1,3,4,6,undefined

 如果我把o属性未定义的元素移到o属性为3的元素下面,则返回结果是:

1,3,undefined,4,6

这正是我的疑惑,如果你知道答案,请不吝赐教。

 

  那么ie8的sort的自定义比较函数是不是无论返回什么都不报错呢?答案是否定的,如果我把比较函数的返回值硬编码成“return “#@#@””,则ie8也报错了:

 

 

   因此,我认为ie8的的sort函数,相比IE6和ie7,至少进行了体验上的优化,即如果发现自定义比较函数的返回值是NaN,则不报错,只是排序可能会出现非预期的结果而已,但是如果返回值是字符串,则将严惩不贷,弹出令人震惊的错误框。

 

 

posted on 2011-05-20 16:39  lola  阅读(1760)  评论(1编辑  收藏  举报