锁定老帖子 主题:indexOf 与比较操作
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (7)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-17
最后修改:2010-08-30
现在我已经大量在平时应用中应用Extjs core,问题也时常发生,如 Ext.DomHelper 添加 option 问题 ,
今天又遇到了一个Ext使用中很重要但容易忽略问题 ,与大家共享: 如下面代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>indexOf 测试</title> <script type="text/javascript" src="ext-base.js"></script> <script type="text/javascript" src="ext-core.js"></script> <script type="text/javascript"> Ext.onReady(function() { /* Array.prototype['indexOf']= function(o){ for (var i = 0, len = this.length; i < len; i++){ if(this[i] == o) return i; } return -1; }; */ var x=[5001, 5003, 5004]; var y='5001'; var z=x.indexOf(y); alert(z); }); </script> </head> <body> </body> </html>
根据 Extjs API 文档 ,
indexOf
( Checks whether or not the specified object exists in the
array.
Checks whether or not the specified object exists in the array.
Parameters:
先不管 是否他是 完全相等 (===) 或 相容相等(==)
,至少我们期望在各个浏览器上表现一致,但是很不幸,据我测试
ie 系列 : alert 0
firefox 系列 : alert -1
那么查看 Extjs 的源代码:(注意: 代码存在 ext-2.2.1/adapter/ext-base.js 与 source/core/Ext.js 并不存在于 source/adapter/ext-base.js
)
Ext.applyIf(Array.prototype, { indexOf : function(o){ for (var i = 0, len = this.length; i < len; i++){ if(this[i] == o) return i; } return -1; }, 可见 Ext 采用的是相容相等,但是又采用了 Ext.applyIf,那么可以分析到 firefox 并没有得到这个方法:
firefox从1.5 就实现了JavaScript 1.6 (非 ecmascript 标准),而 Array 的 indexOf 方法正是从1.6成为原生方法
而 ie (直至最新的ie8) 实现 ecmascript 标准 262 即 javascrip 1.5,Array 并无 indexOf方法,于是由extjs 设置。
http://en.wikipedia.org/wiki/JavaScript
而 javascrip 1.6 中明确规定是对象在数组中出现的索引,即采用的是严格相等,而 ie 执行extjs 设置的相容相等,这也正解释了为什么 ie ff 会在这个问题上表现不一致。
https://developer.mozilla.org/En/Core_javascript_1.5_reference:objects:array:indexof
我认为 Extjs 需对此负一定责任, John Resig 曾说过库是用来屏蔽各个浏览器差异的 ,而 这个问题正是体现了两个浏览器的迥然不同。
John Resig
Advancing JavaScript with Libraries(2)
对于 Extjs 使用的相容相等,觉得也不是很好,对于这方面应该尽量使用严格相等 ===
,在 Douglas Crockford 的
Douglas Crockford
The JavaScript Programming Language(2)
The JavaScript Programming Language(3)
The JavaScript Programming Language(4)
总之很简单的解决:这个改成 === 就可以了,不过不知道为什么这个问题在Ext3.0 beta 中仍然没有改变.
附录 : == 使用注意
参见 ecma262
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
所以 == 可能会抛出异常的:
var b={ toString :function(){ return {}; }, valueOf : function(){ return {}; } }; try{ alert(b == 'a'); } catch(e){alert(e);} 再试试这个:
"true" == true
ps:ecma262-5rd 的一些备注
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-04-18
var y='5001'是字符串,怎么能和整数数组比较?
改成var y=5001 |
|
返回顶楼 | |
发表时间:2009-04-18
最后修改:2009-04-18
这不算是bug,把y改成整数后,ie也通过了。如果按照你要求的,倒是bug了。
|
|
返回顶楼 | |
发表时间:2009-04-18
netharry 写道 var y='5001'是字符串,怎么能和整数数组比较?改成var y=5001 照你那么说的话 == 和 === 有在语言规范中同时存在的必要么?这是 javascript 不是 java ,javascript 弱类型 这种比较很常见 ,内存里你存的是 number 数组,从 input 取来的都是 string ,这两者比较很常见 |
|
返回顶楼 | |
发表时间:2009-04-18
netharry 写道 这不算是bug,把y改成整数后,ie也通过了。如果按照你要求的,倒是bug了。 我现在讨论的是 indexOf 这个在 ff ie浏览器表现一致性问题 , 不管 indexOf 的输入是什么 |
|
返回顶楼 | |
发表时间:2009-04-18
我对js了解并不多,但我知道:
add=function(a,b){ return a+b; } alert(add(1,4))和alert(add('1','4'))并不是一回事。而且有个toString(),我想不会是个摆设。 |
|
返回顶楼 | |
发表时间:2009-04-20
最后修改:2009-04-20
这个勉强算是个bug,就好像我们利用算符优先法则可以少写很多的括号,但是一般正常的程序员编程序的时候都不会这么做。
不同编译器和解释器定义的优先规则也是不一样的。 |
|
返回顶楼 | |
发表时间:2009-06-13
这个不是Bug哦,FireFox实现了原生Array的indexOf()方法(其它浏览器IE、Opera、Safari都没有原生实现),在扩展的时候用的是Ext.applyIf(...),也就是说,如果有原生实现就不拿Ext自己的实现去覆盖。我当初也纳闷来着。。。
|
|
返回顶楼 | |
发表时间:2009-06-13
damoqiongqiu 写道 这个不是Bug哦,FireFox实现了原生Array的indexOf()方法(其它浏览器IE、Opera、Safari都没有原生实现),在扩展的时候用的是Ext.applyIf(...),也就是说,如果有原生实现就不拿Ext自己的实现去覆盖。我当初也纳闷来着。。。 你看清楚我写的东西了么?.... |
|
返回顶楼 | |
发表时间:2009-06-15
LZ并不是说EXT实现的indexOf有BUG,而是说本身的实和原生的实现不一致,进而造成同样的库在不同浏览器里表现不一致而产生使用陷井,这才是BUG
|
|
返回顶楼 | |