发表于 & 归档在 Web.

JavaScript中的比较操作符Equality(==)和Identity(===),以及类型间的转换是让人头疼的问题,虽然很多情况下都不需要,但多了解些,备特殊之需:

一道有名的javascript题目,其中有一处判断语句如下:

alert([] == ![])

简单解答

1、”![]”结果是什么?

[]转换成boolean,按ToBoolean规则,object转换成boolean,返回true,然后取反,所以“![]”的结果是false

2、”[] == ![]”结果是什么?

看等号的左右两边,一个类型是object,一个是boolean,按不同类型对象间比较的规则:

[]” 转化成number ,结果是0

false,转换成number,结果是0

所以[] == ![] 结果为true,问题的关键是object和boolean比较,先转换成number(ToNumber())然后比较。

3、”[] == ![]”始终为真吗?

答案是否定,上面的结论是默认的情况,如果重写Array.prototype.valueOf方法,定制array转换成 number的过程,可以得到不同的结果,如:

Array.prototype.valueOf = function(){
    return 1;
}
//结果是false
alert([] == ![]);

详细解释

前面的例子中涉及到不同类型之间的比较和转化,在ECMAScript规范中对这些都有描述(见ECMA 262 – 9 Type Conversion and Testing)。

类型转换

1、ToBoolean

ToBoolean比较简单,规则如下:

Boolean : 不变

Undefined/Null : false

Number : +0, -0, NaN –> false 其他为 true

String : ” –> false 其他为 true

Object : true

2、ToNumber

ToNumber要复杂些,对于object类型的,需要先转换成原始值(ToPrimitive()),然后在ToNumber()

参数(arg) 结果
Undefined NaN
Null +0
Boolean true –> 1 , false –> 0
Number 不变
String 情况比较多,很多种写法都可以转换,如 5.2e6 或者 0xff,详见ECMA 262 – 9.3.1 ToNumber Applied to the String Type
Object 先value = ToPrimitive(arg)再ToNumber(value)

补充:

object转换成number:涉及到ToPrimitive,找[DefaultValue],详见 ECMA 262 – 8.12.8,简单的说会先object.valueOf()或者object.toString(),如果对象没有这些方法,则找基类的相关方法

比较规则(Equality & Identity)

JavaScript中除去”null”, “undefined” 外,有四种基本类型,string, boolean, number, object,四种类型之间的比较分两类,一类是相同类型之间的比较,一类是不同类型间的比较

1、”===”比较规则

1、如果类型不一致,返回false

2、number,如果相同值,返回true,NaN不等于任何值,包括他自己,NaN可通过全局方法,isNaN(…)判断

3、string,相同字符序列的返回true,有一种情况,相同的字符串使用Unicode标准可能有不同的编码方式,但遗憾的是,javascript只通过基本的字符比较,所有的字符串在比较之前,会先转换成“正常格式”。参考”String.localeCompare()”提供另一种比较字符串的方式

4、boolean,同为true或false,返回true

5、相同引用表示是同一个对象

6、如果两者都是null或者都是undefined,表示他们相同

2、”==”比较规则

相同类型的比较

相同类型之间的比较,有的人说等同于”===”,准确的说要除去null 和 undefined外,因为null == undefined ,但 null !== undefined ,余下的按===的规则:

不同类型之间的比较

不同类型间,按排列组合存在六种情况,先通过类型转换,然后进行比较:

1、number , string >>> string转换成number,然后比较

2、number , boolean >>> boolean转换成number,然后比较

3、number , object >>> object转换成number,然后比较

4、string , object >>> object.toString(),然后比较

5、object , boolean >>> boolean转换成number,object转换成number,然后比较

6、string, boolean >>> string转换成number, boolean转换成number,然后比较

发表评论

电子邮件地址不会被公开。 必填项已用*标注


+ 九 = 14

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>