龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

JavaScript中的陷阱大集合(1)(3)

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
杂项 数据不存在:null和undefined 有两种对象状态来表明数据不存在:null和undefined。这会让那些从其他编程语言比如C#转过来的程序员变得相当混乱。也许你

杂项

数据不存在:”null“和”undefined“

有两种对象状态来表明数据不存在:null和undefined。这会让那些从其他编程语言比如C#转过来的程序员变得相当混乱。也许你会期望下面的代码返回true:

  1. var a;  
  2. a === null//false  
  3. a === undefined; //true 

”a“实际上是undefined的(尽管你用双等号==来与null比较会得出true的结果,但这只是表面上看起来正确的另一个错误)。

如果你想检查一个变量是否真的存在值,那你不能用双等号==去判断,要用下面的方法:

  1. if(a !== null && a !== undefined) {  
  2.     ...  

”哈“,你也许会说,既然null和undefined都是false,那么你可以这样去做:

  1. if(a) {  
  2.     ...  

当然,0是false,空字符串也是。那么如果这其中一个是a的正确的值的话,你就要用前者了。那种比较短小的比较方式,适合于比较objects, arrays, 和booleans类型。

重定义undefined

非常正确,你可以重定义undefined,因为它不是一个保留字:

  1. undefined = "surprise!"

但是,你要通过给undefined变量分配一个值或者使用”void“操作符来取回值(否则这是相当没用的)。

  1. undefined = void 0; 

这就是为什么jquery脚本库的第一行要这样写了:

  1. (function ( window, undefined ) {  
  2.     ... // jQuery library!  
  3. }(window)); 

这个函数被调用时是传入一个参数的,同时确保了第二个参数”undefined“实际上是undefined的。

顺便说一下,你不能重定义null - 但是你可以重定义NaN,Infinity和带构造函数的内置类型。可以这样尝试一下:

  1. Array = function (){ alert("hello!"); }  
  2. var a = new Array(); 

当然,你可以在任何地方用文字语法声明Array。

可选的分号

Javascript代码中分号是可选的,所以初学者写代码就简单多了。但是很不幸的是如果忽略了分号并不会给任何人带来方便。结果是当解释器遇到错误时,必须追溯并尝试去猜测因为哪些分号漏写导致的问题。

这里有一个经典的例子:

  1. return 
  2. {  
  3.     a: "hello" 
  4. }; 

上面的代码并不会返回一个对象,而是返回了undefined - 但是也没有错误抛出。其实是因为分号自动加到了return语句后面,其他的代码都是非常正确的,但是就是什么都不执行,这就证明了在 javascript中,左花括号应该紧跟这一行而不该换行,这不只是一个编程风格的问题。下面的代码才会正确返回一个属性为a的对象:

  1. return {  
  2.     a: "hello" 
  3. }; 

NaN

NaN的类型是...Number

  1. typeof NaN === "number" //true 

另外NaN和任何东西比较都是false:

  1. NaN === NaN; // false 

因为NaN之间是不能比较的,唯一判断一个数字是否为NaN的方法是调用isNaN方法。

从另一个方面可以说明,我们也可以用函数isFinite,当其中一个操作数为NaN或者InFinity时返回false。

arguments对象

在一个函数中,我们可以引用arguments对象来遍历传入的参数列表,第一个比较怪异的地方是这个对象并不是Array,而是一个类似 Array的对象(有一个length属性,其值在0-length-1之间)。为了将其转换成array,我们可以array的splice函数来创建 其对应的array数组:

  1. (function(){  
  2. console.log(arguments instanceof Array); // false  
  3. var argsArray = Array.prototype.slice.call(arguments);  
  4. console.log(argsArray instanceof Array); // true  
  5. }()); 

第二个比较怪异的地方是当一个函数的签名中有显式arguments参数时,它们是可以被重新分配的并且arguments对象也会被改变。这就表明了arguments对象指向了变量本身。你不能利用arguments对象来给出它们的初始值:

  1. (function(a){  
  2.     alert(arguments[0]); //1  
  3.     a = 2;  
  4.     alert(arguments[0]); //2  
  5. }(1)); 

结束本文!

这样我就总结完了这些javascript陷阱。我肯定还会有更多这样的陷阱,期待大家更多的意见和点评。

PS - 我真的很喜欢Javascript。

原文:http://www.codeproject.com/KB/scripting/javascript-gotchas.aspx

译文:http://www.cnblogs.com/sxwgf/archive/2011/11/14/javascript-gotchas.html

译者:王国峰

精彩图集

赞助商链接