关于javascript的类型自动转换的疑问

var a;         // undefined
!a             // true
a == false     // false

a = null;
!a             // true
a == false     // false

上面的代码中,为什么!a中a能转换成false, 而a == false 中a就不能转换成false呢?JS中关于类型自动转换是有遵循什么样的原则?

阅读 5.9k
7 个回答

这是由JS的比较转换规则设定的~

!(逻辑非操作)
其期望其操作数为一个boolean值,对其求反操作。首先会将操作数转换为boolean值
任何对象转换为boolean值都为true
undefined对应的boolean值为false
null对应的boolean值为false
空字符串为false
非空字符串为true
非零数字为true
0为false
NaN为false

==操作符

==操作符不会尝试将左右操作数转换为boolean值后再进行比较
==操作符的比较有自己的规则:
如果2个操作数类型相同,那么同===(恒等操作符)比较结果
如果2个操作数类型不同,按如下:

  1. 如果一个值为null,另一个为undefined,则它们相等

  2. 如果一个为数字,另一个为字符串,那么将字符串转化为数字后,再进行比较

  3. 如果其中一个值为true,则将其转化为数字1;另一个为false,转化为0,在进行比较

  4. 如果一个值为对象,另一个为数字或字符串,那么向将对象转换为原始值,先使用valueOf转化为原始值,不能转换为原始值的再尝试使用toString方法转换为原始字符串

  5. 其它的不同类型的比较就为不相等

a为undefined/null时,
a==false 符合规则5,为false

对于取反操作
undefined和null都将转成boolean值false,取反!a后为true

boolean转换规则如下

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""空字符串
Number 任何非0数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined n/a undefined

数据来源《javascript高级编程》

var a;这个时候a是undefined
你的问题从基本类型这儿讲起,可能会让你理解的更深刻一些。

javascript的基本类型

javascript中有五种基本类型。

null , undefined  , boolean , string , number

比较运算 x==y, 其中 x 和 y 是值,产生 true 或者 false。
这样的比较按如下方式进行。若 Type(x) 为 Boolean, 返回比较 ToNumber(x) == y 的结果。
这儿false转换为number后,和undefined不同,返回false。

至于为什么的话,只能说规范规定是这样的。可以看下面的链接。

http://segmentfault.com/q/1010000000305997

那是为什么!atrue
!是逻辑非操作,可以应用于javascript中的任何值,并返回一个bool值。逻辑非操作符首先会将要操作的值转化为bool值,然后再对其进行求反undefined转化为bool值是false,取反后就是true了。

类型转换的规则

javascript中类型转换的规则比较多,推荐去看《javascript高级程序设计》的第三章。

Javascript类型转换的规则

为什么!a中a能转换成false
这个很好回答~
那是因为用了!这个符号,这个符号属于逻辑运算符。
逻辑运算符通常会返回一个布尔型值;
**逻辑非(!) 如果单个表达式能转换为true的话返回false,否则返回true.
能够转换为false的表达式有:null,0,""和undefined.**
所以!a会返回 true。这是因为逻辑非(!)将a转换成了布尔值

而a == false 中a就不能转换成false呢?
这个算是设计缺陷罢。
因为(==)在比较的时候,可以自动转换数据类型,有时候用起来确实会出现比较诡异的比较结果。
而undefined 严格来说,也算是全局的一个属性,又是一种数据类型。可能问题出在这儿吧
在写代码的时候,尽量用(===)去做真实的判断,少用(==)。

规范上说得很清楚啊。见ECMAScript规范11.4.9章节

11.4.9 Logical NOT Operator ( ! )
The production UnaryExpression : !UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression.

  2. Let oldValue be ToBoolean(GetValue(expr)).

  3. If oldValue is true, return false.

  4. Return true.

所以原因就是,逻辑非在运算的时候JS引擎就是会把操作数转为布尔类型啊。

这个问题,还是建议题主去读一下《JavaScript高级程序设计(第三版)》里面的章节专门关于这个的讲解,讲的比较透彻,好好看看你就会完全明白了!

推荐问题
宣传栏