JavaScript有关的10个秘密和怪癖(1)


数据类型和定义


1. Null是个对象


JavaScript众多类型中有个Null类型,它有个唯一的值null, 即它的字面量,定义为完全没有任何意义的值。其表现得像个对象,如下检测代码:


  1. alert(typeof null); //弹出 'object' 

如下截图:





尽管typeof值显示是"object",但null并不认为是一个对象实例。要知道,JavaScript中的值都是对象实例,每个数值都是Number对象,每个对象都是Object对象。因为null是没有值的,所以,很明显,null不是任何东西的实例。因此,下面的值等于false。


  1. alert(null instanceof Object); //为 false 

译者注:null还有被理解为对象占位符一说


2. NaN是个数值


NaN本意是表示某个值不是数值,但是其本身却又是数值,且不等于其自身,很奇怪吧,看下面的代码:


  1. alert(typeof NaN); //弹出 'Number'  
  2. alert(NaN === NaN); //为 false 

结果如下截图:





实际上NaN不等于任何东西。要确认某玩意是不是NaN只能使用isNaN.


3. 无关键字的数组等同于false(关于Truthy和Falsy)


下面是JavaScript另一个极品怪癖:


  1. alert(new Array() == false); //为 true 

结果如下截图:





想要知道这里发生了什么,你需要理解truthy和falsy这个概念。它们是一种true/flase字面量。在JavaScript中,所有的非Boolean型值都会内置一个boolean标志,当这个值被要求有boolean行为的时候,这个内置布尔值就会出现,例如当你要跟Boolean型值比对的时候。


因为苹果不能和梨做比较,所以当JavaScript两个不同类型的值要求做比较的时候,它首先会将其弱化成相同的类型。false, undefined, null, 0, "", NaN都弱化成false。这种强制转化并不是一直存在的,只有当作为表达式使用的时候。看下面这个简单的例子:


  1. var someVar =0;  
  2. alert(someVar == false); //显示 true 

结果如下截图:





上面测试中,我们试图将数值0和boolean值false做比较,因两者的数据类型不兼容,JavaScript自动强制转换成统一的等同的truthy和falsy,其中0等同于false(正如上面所提及的)。


你可能注意到了,上面一些等同false的值中并没有空数组。只因空数组是个怪胚子:其本身实际上属于truthy,但是当空数组与Boolean型做比较的时候,其行为表现又属于falsy。不解?这是由原因的。先举个例子验证下空数组的奇怪脾气:


  1. var someVar = []; //空数组  
  2. alert(someVar == false); //结果 true  
  3. if (someVar) alert('hello'); //alert语句执行, 所以someVar当作true 

结果如下截图,连续弹出两个框框:





译者注:之所以会有这种差异,根据作者的说法,数组内置toString()方法,例如直接alert的时候,会以join(“,”)的形式弹出字符串,空数组自然就是空字符串,于是等同false。具体可参见作者另外一篇文章,《Twisted logic: understanding truthy & falsy》。不过我个人奇怪的是,像空对象,空函数,弱等于true或者false的时候都显示false,为何?真的因为数组是个怪胎,需要特殊考虑吗?


为避免强制转换在比较方面的问题,你可以使用强等于(===)代替弱等于(==)。


  1. var someVar = 0;  
  2. alert(someVar == false); //结果 true – 0属于falsy  
  3. alert(someVar === false); //结果 false – zero是个数值, 不是布尔值 

结果如下截图(win7 FF4):





如果你想深入探究JavaScript中类型强制转换等些特有的癖好,可以参见官方相关的文档规范:section 11.9.3 of the ECMA-262





标签:

友情链接
轻松育儿世界奇观
苏ICP备16066217号-2