`
yiminghe
  • 浏览: 1460372 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

indexOf 与比较操作

阅读更多

 

  现在我已经大量在平时应用中应用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 ( Object o  ) : Number

Checks whether or not the specified object exists in the array.
Checks whether or not the specified object exists in the array.
Parameters:
  • o : Object
    The object to check for
Returns:
  • Number
    The index of o in the array (or -1 if it is not found)

先不管 是否他是 完全相等 (===) 或 相容相等(==) ,至少我们期望在各个浏览器上表现一致,但是很不幸,据我测试

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(1)


http://video.yahoo.com/watch/410472/2391234

 

Advancing JavaScript with Libraries(2)


http://video.yahoo.com/watch/412541/2395771

 

 

 

对于 Extjs 使用的相容相等,觉得也不是很好,对于这方面应该尽量使用严格相等 === ,在 Douglas Crockford 的
The JavaScript Programming Language 讲座中也提到过。

 

Douglas Crockford
The JavaScript Programming Language(1)


http://video.yahoo.com/watch/111593/1710507

 

The JavaScript Programming Language(2)


http://video.yahoo.com/watch/111594/1710553

 

The JavaScript Programming Language(3)


http://video.yahoo.com/watch/111595/1710607

 

The JavaScript Programming Language(4)


http://video.yahoo.com/watch/111596/1710658

 

 

总之很简单的解决:这个改成 ===  就可以了,不过不知道为什么这个问题在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:
1.    If Type(x) is different from Type(y), go to step 14.
2.    If Type(x) is Undefined, return true.
3.    If Type(x) is Null, return true.
4.    If Type(x) is not Number, go to step 11.
5.    If x is NaN, return false.
6.    If y is NaN, return false.
7.    If x is the same number value as y, return true.
8. Ifxis+0andyis−0,returntrue.
9. Ifxis−0andyis+0,returntrue.
10. Return false.
11.If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same
length and same characters in corresponding positions). Otherwise, return false.
12. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
13.Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false.
14. If x is null and y is undefined, return true.
15. If x is undefined and y is null, return true.
16.If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
17.If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
18. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
20.If Type(x) is either String or Number and Type(y) is Object,return the result of the comparison x == ToPrimitive(y).
21.If Type(x) is Object and Type(y) is either String or Number,return the result of the comparison ToPrimitive(x) == y.
22. Return false.


ToPrimitive :
1.    Call the [[Get]] method of object O with argument "valueOf".
2.    If Result(1) is not an object, go to step 5.
3.    Call the [[Call]] method of Result(1), with O as the this value and an empty argument list.
4.    If Result(3) is a primitive value, return Result(3).
5.    Call the [[Get]] method of object O with argument "toString".
6.    If Result(5) is not an object, go to step 9.
7.    Call the [[Call]] method of Result(5), with O as the this value and an empty argument list.
8.    If Result(7) is a primitive value, return Result(7).
9.    Throw a TypeError exception.


所以 == 可能会抛出异常的:

 

var b={
    toString :function(){
return {};    
},

valueOf : function(){
    return {};
}
};

try{
alert(b == 'a');
}
catch(e){alert(e);}

 

再试试这个:

 

"true" == true

 

通俗的解释可参见玉伯的总结:例子 以及解释

 

ps:ecma262-5rd 的一些备注

1.一些省心的诀窍,免得读代码的其他人不熟悉转换规则
String comparison can be forced by: "" + a == "" + b.

Numeric comparison can be forced by: +a == +b.

Boolean comparison can be forced by: !a == !b.

2.注意 == 不具有传递性:

var a=new String("xx");var b= "xx" ;var c=new String("xx");
a==b ,b==c but a!=c

 

分享到:
评论
11 楼 witcheryne 2009-06-16  
xuzhfa123 写道
请问LZ‘==’与'==='有什么区别,有什么共同点?

关系运算符(<、>、<=、>=)

试图将 expression1 和 expression2 都转换为数字。
如果两表达式均为字符串,则按字典序进行字符串比较。
如果其中一个表达式为 NaN,返回 false。
负零等于正零。
负无穷小于包括其本身在内的任何数。
正无穷大于包括其本身在内的任何数。
相等运算符 (==、!=)

如果两表达式的类型不同,则试图将它们转换为字符串、数字或 Boolean 量。
NaN 与包括其本身在内的任何值都不相等。
负零等于正零。
null 与 null 和 undefined 相等。
相同的字符串、数值上相等的数字、相同的对象、相同的 Boolean 值或者(当类型不同时)能被强制转化为上述情况之一,均被认为是相等的。
其他比较均被认为是不相等的。
恒等运算符 (===、!==)

除了不进行类型转换,并且类型必须相同以外,这些运算符与相等运算符的作用是一样的。
摘自《JavaScript语言参考》
10 楼 xuzhfa123 2009-06-16  
请问LZ‘==’与'==='有什么区别,有什么共同点?
9 楼 lqql 2009-06-15  
LZ并不是说EXT实现的indexOf有BUG,而是说本身的实和原生的实现不一致,进而造成同样的库在不同浏览器里表现不一致而产生使用陷井,这才是BUG
8 楼 yiminghe 2009-06-13  
damoqiongqiu 写道

这个不是Bug哦,FireFox实现了原生Array的indexOf()方法(其它浏览器IE、Opera、Safari都没有原生实现),在扩展的时候用的是Ext.applyIf(...),也就是说,如果有原生实现就不拿Ext自己的实现去覆盖。我当初也纳闷来着。。。


你看清楚我写的东西了么?....
7 楼 damoqiongqiu 2009-06-13  
这个不是Bug哦,FireFox实现了原生Array的indexOf()方法(其它浏览器IE、Opera、Safari都没有原生实现),在扩展的时候用的是Ext.applyIf(...),也就是说,如果有原生实现就不拿Ext自己的实现去覆盖。我当初也纳闷来着。。。
6 楼 yangyi 2009-04-20  
这个勉强算是个bug,就好像我们利用算符优先法则可以少写很多的括号,但是一般正常的程序员编程序的时候都不会这么做。
不同编译器和解释器定义的优先规则也是不一样的。
5 楼 netharry 2009-04-18  
我对js了解并不多,但我知道:
add=function(a,b){
  return a+b;
}
alert(add(1,4))和alert(add('1','4'))并不是一回事。而且有个toString(),我想不会是个摆设。
4 楼 yiminghe 2009-04-18  
netharry 写道

这不算是bug,把y改成整数后,ie也通过了。如果按照你要求的,倒是bug了。

我现在讨论的是 indexOf 这个在 ff ie浏览器表现一致性问题 , 不管 indexOf 的输入是什么
3 楼 yiminghe 2009-04-18  
netharry 写道

var y='5001'是字符串,怎么能和整数数组比较?改成var y=5001


照你那么说的话  == 和 === 有在语言规范中同时存在的必要么?这是 javascript 不是 java ,javascript 弱类型 这种比较很常见 ,内存里你存的是 number 数组,从 input 取来的都是 string ,这两者比较很常见


2 楼 netharry 2009-04-18  
这不算是bug,把y改成整数后,ie也通过了。如果按照你要求的,倒是bug了。
1 楼 netharry 2009-04-18  
var y='5001'是字符串,怎么能和整数数组比较?
改成var y=5001

相关推荐

    js中indexof的用法详细解析.docx

    `lastIndexOf` 方法与 `indexOf` 类似,但它返回的是指定字符或子字符串在字符串中最后一次出现的位置,而不是第一次。同样支持 `fromIndex` 参数。 ```javascript let str = "Hello, World! Hello again."; ...

    Node.js-Node.js4.0`buffer.indexOf()`ponyfill

    3. 当你需要使用`indexOf`功能时,你可以调用`bufferIndexOf(buffer, searchValue[, byteOffset])`,这里的参数与原生`buffer.indexOf()`相同。 通过这种方式,即使在Node.js 4.0或更低版本的环境中,你也能享受到...

    JS判断是否包含某字符串indexOf方法

    `lastIndexOf`方法与`indexOf`类似,但它的搜索方向相反,是从字符串的末尾开始向前查找。如果在字符串中找到子字符串,它会返回子字符串最后一次出现的索引。如果未找到,也会返回-1。因此,当需要确定子字符串...

    前端开源库-sorted-indexof

    这与 JavaScript 内置的 `indexOf` 方法不同,后者在未排序的数组中寻找元素时会遍历整个数组,时间复杂度为 O(n)。而 `sorted-indexof` 库利用了数组已排序的特点,采用更高效的算法,通常可以在 O(log n) 时间...

    C# 数组中的 indexOf 方法及使用

    这些方法与 indexOf 方法类似,但它们接受一个字符数组作为参数,并返回数组中任何一个字符最早出现的下标位置。 例如: ``` char[] bbv = { 's', 'c', 'b' }; string abc = "acsdfgdfgchacscdsad"; Response.Write...

    jquery indexOf使用方法

    总之,`indexOf()`和`lastIndexOf()`是JavaScript中非常实用的字符串和数组操作方法,无论在纯JavaScript还是在使用`jQuery`的场景下,都能帮助我们快速定位到目标子字符串或元素的位置。在进行文本处理、数据查找等...

    基于Java中字符串indexof() 的使用方法

    例如,我们可以使用 indexOf() 方法来查找字符串中是否包含某个子字符串,然后根据结果进行相应的操作。 总结 Java 中的 indexOf() 方法是一个非常有用的方法,它可以帮助我们快速地查找字符串中子字符串的位置。...

    Array.prototype.indexOf:符合ES2015规范的“ Array.prototype.indexOf” shimpolyfillreplacement可以向下使用到ES3

    因为Array.prototype.indexOf依赖于接收方(“ this”值),所以Array.prototype.indexOf出将数组作为第一个参数进行操作。 例子 var indexOf = require ( 'array.prototype.indexof' ) ; var assert = require ( '...

    JavaScript indexOf忽略大小写

    下面像大家介绍如何让javascript中... [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]下面这个兼容原来的 indexOf函数,可以加入直接拿来进行忽略大小写的javascript的indexOf函数操作了。 [Ctrl+A 全选 注:如需

    Index of the Bash Command Lin for Linux

    Bash命令行是Linux操作系统中的主要交互界面,它提供了丰富的功能,使得用户可以通过文本命令高效地管理操作系统。本文将详细介绍Linux Bash命令行中的各种命令,帮助用户理解和掌握这个强大的工具。 ### 基本命令 ...

    js中indexof的用法详细解析

    JavaScript 中的 `indexOf` 方法是字符串对象的一个核心方法,用于查找子字符串或者单个字符在原字符串中首次出现的位置。这个方法对于处理字符串数据时的搜索和定位非常有用。下面我们将详细解析 `indexOf` 的用法...

    JavaScript indexOf()原理及使用方法详解

    值得注意的是,`indexOf()`方法区分大小写,因此在比较时,"hello"与"Hello"会被视为不同的字符串。 ### 2. 使用方法 `indexOf()`方法的基本语法如下: ```javascript stringObject.indexOf(searchvalue, ...

    JavaScript indexOf方法入门实例(计算指定字符在字符串中首次出现的位置)

    在使用indexOf方法时,必须确保指定的字符或字符串的大小写与目标字符串中的一致。 ### 检索失败的返回值 如果指定的字符或字符串没有在目标字符串中出现,indexOf方法将返回`-1`。 ### 代码注意事项 在使用...

    C#判断字符串中是否包含指定字符串及contains与indexof方法效率问题

    C#判断字符串中是否包含指定字符串及contains与indexof方法效率问题 C#中判断字符串中是否包含指定字符串是非常常见的操作,常用的方法有两种:使用string.Contains方法和使用string.IndexOf方法。下面详细介绍这两...

    Arduino项目开发 Strings_StringIndexOf_StringIndexOf.pdf

    `lastIndexOf()`函数则与`indexOf()`相反,它返回字符串中最后一次出现指定字符或子字符串的位置。同样,如果没有找到则返回-1。基本语法如下: ```cpp int lastIndexOf(const char* str); int lastIndexOf(const ...

    js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解

    本文将详细介绍JavaScript中一些常用字符串方法的用法,包括 substr、substring、indexOf、lastIndexOf、split 和 replace。通过这些方法,可以轻松地对字符串进行提取、分割和替换操作。 首先,让我们来看看 ...

    JavaScript Array对象扩展indexOf()方法

    通过这样的扩展,开发者可以使用indexOf()方法在任何数组上进行操作,这极大地增强了代码的可读性和功能的完整性。 需要注意的是,ECMAScript 5引入了数组的indexOf()方法作为标准化的一部分。因此,在支持ES5及...

    String index out of 4解决方法

    ### String index out of 4解决方法 在编程中,尤其是使用Java进行字符串处理时,经常会遇到`StringIndexOutOfBoundsException`异常。这种异常通常发生在试图访问一个不存在的字符串索引时。例如,如果尝试访问一个...

    js代码-js数组查找元素:indexOf() 方法

    `indexOf()`会从`fromIndex`位置开始遍历数组,逐个比较每个元素与`searchElement`是否相等。如果找到相等的元素,就返回该元素的索引;如果遍历完整个数组都没有找到匹配项,那么返回-1。 **基本用法:** ```...

Global site tag (gtag.js) - Google Analytics