自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaScript中的陷阱大集合

開(kāi)發(fā) 前端
本文主要介紹怪異的Javascript,毋庸置疑,它絕對(duì)有怪異的一面。當(dāng)軟件開(kāi)發(fā)者開(kāi)始使用世界上使用最廣泛的語(yǔ)言編寫(xiě)代碼時(shí),他們會(huì)在這個(gè)過(guò) 程中發(fā)現(xiàn)很多有趣的“特性”。即便是老練的Javascript開(kāi)發(fā)者也可以在本文找到一些有趣的新陷阱,請(qǐng)留意這些陷阱,當(dāng)然也可以盡情享受由這些陷阱 帶來(lái)的“樂(lè)趣”!

本文主要介紹怪異的Javascript,毋庸置疑,它絕對(duì)有怪異的一面。當(dāng)軟件開(kāi)發(fā)者開(kāi)始使用世界上使用最廣泛的語(yǔ)言編寫(xiě)代碼時(shí),他們會(huì)在這個(gè)過(guò) 程中發(fā)現(xiàn)很多有趣的“特性”。即便是老練的Javascript開(kāi)發(fā)者也可以在本文找到一些有趣的新陷阱,請(qǐng)留意這些陷阱,當(dāng)然也可以盡情享受由這些陷阱 帶來(lái)的“樂(lè)趣”!

函數(shù)和操作符

雙等號(hào)

==操作符比較時(shí)會(huì)進(jìn)行類(lèi)型的強(qiáng)制轉(zhuǎn)換,這意味著它可以比較兩個(gè)不同類(lèi)型的對(duì)象,在執(zhí)行比較之前它將會(huì)嘗試把這兩個(gè)對(duì)象轉(zhuǎn)換成同一個(gè)類(lèi)型,舉一個(gè)例子:

  1. "1" == 1 //true 

然而,這樣往往會(huì)誤導(dǎo)我們,而且我們也不需要這樣子來(lái)比較。在上面的例子中,我們完全可以先將字符串轉(zhuǎn)換成數(shù)字型,然后利用對(duì)類(lèi)型敏感的三重等號(hào)(===)來(lái)進(jìn)行比較,如:

  1. Number("1") === 1; //true 

或者,更好的是,確保你放在首位的操作數(shù)的類(lèi)型是正確的。

由于雙等號(hào)具有強(qiáng)制類(lèi)型轉(zhuǎn)換的行為,所以它會(huì)打破一般的傳遞性規(guī)則,這點(diǎn)有點(diǎn)嚇人,請(qǐng)看下面的列子:

  1. "" == 0 //true - 空字符串會(huì)被強(qiáng)制轉(zhuǎn)換為數(shù)字0.  
  2. 0 == "0" //true - 數(shù)字0會(huì)被強(qiáng)制轉(zhuǎn)換成字符串"0"  
  3. "" == "0" //false - 兩操作數(shù)都是字符串所以不執(zhí)行強(qiáng)制轉(zhuǎn)換 

如果使用三重等號(hào),上面的三個(gè)比較都將返回false。

parseInt不把10作為數(shù)字基數(shù)

如果你忽略parseInt的第二個(gè)參數(shù),那么數(shù)字的基數(shù)將由下面的規(guī)則所決定:

◆ 默認(rèn)基數(shù)為10,即按10進(jìn)制解析

◆ 如果數(shù)字以0x開(kāi)頭,那么基數(shù)為16,即按16進(jìn)制解析

◆ 如果數(shù)字以0開(kāi)頭,那么基數(shù)為8,即按8進(jìn)制解析

一個(gè)常見(jiàn)的錯(cuò)誤是我們讓用戶(hù)輸入以0開(kāi)頭的數(shù)字,這時(shí)候它就按8進(jìn)制的方式去解析了,于是我們就看到了如下的效果:

  1. parseInt("8"); //8  
  2. parseInt("08"); //0 

因此,我們很多時(shí)候都會(huì)指定parseInt的第二個(gè)參數(shù),如下所示:

  1. parseInt("8", 10); //8  
  2. parseInt("08", 10); //8 

ECMAScript5方面的說(shuō)明:ECMAScript已不再支持8進(jìn)制的解析假設(shè),另外,如果忽略parseInt的第二個(gè)參數(shù)將會(huì)引起JSLint的警告。

字符串替換

字符串替換函數(shù)僅僅會(huì)替換第一個(gè)匹配項(xiàng),并不能替換你所期望的全部匹配項(xiàng)。如下代碼:

  1. "bob".replace("b""x"); // "xob"  
  2. "bob".replace(/b/, "x"); // "xob" (使用了正則表達(dá)式) 

如果要替換所有的匹配項(xiàng),我們可以使用正則表達(dá)式,并為他它添加全局修飾符,如下代碼:

  1. "bob".replace(/b/g, "x"); // "xox"  
  2. "bob".replace(new RegExp("b""g"), "x"); // "xox" (alternate explicit RegExp) 

全局修飾符確保了替換函數(shù)找到第一個(gè)匹配項(xiàng)后不會(huì)停止對(duì)下一個(gè)匹配項(xiàng)的替換。

“+"操作符會(huì)執(zhí)行相加操作和字符串連接操作

php作為另一種弱類(lèi)型語(yǔ)言,可以使用”.“操作符對(duì)字符串進(jìn)行連接。Javascript卻不是這樣的 - 所以當(dāng)操作數(shù)是字符串的時(shí)候”a+b“通常是執(zhí)行連接操作。如果你想執(zhí)行數(shù)字相加那你就要引起注意了,因?yàn)檩斎氲膬?nèi)容可能是字符串類(lèi)型的,所以你在執(zhí)行相 加操作前需要先將其轉(zhuǎn)換成數(shù)字類(lèi)型,代碼如下:

  1. 1 + document.getElementById("inputElem").value; // 連接操作  
  2. 1 + Number(document.getElementById("inputElem").value); // 相加操作 

需要注意的是,相減操作會(huì)嘗試將操作數(shù)轉(zhuǎn)換成數(shù)字類(lèi)型,代碼如下:

  1. "3" - "1"// 2 

盡管有時(shí)候你想用減法將字符串從另一個(gè)字符串中減掉,但這時(shí)候往往會(huì)產(chǎn)生一些邏輯錯(cuò)誤。

很多時(shí)候我們用數(shù)字和空串相加來(lái)實(shí)現(xiàn)數(shù)字轉(zhuǎn)換成字符串的操作,代碼如下:

  1. 3 + ""; // "3" 

但是這樣做并不好,所以我們可以用String(3)來(lái)取代上面的方法。

typeof

typeof這會(huì)返回一個(gè)javascript基本類(lèi)型的實(shí)例的類(lèi)型。Array實(shí)際上不是基本類(lèi)型,所以typeof Array對(duì)象將返回Object,代碼如下:

  1. typeof {} === "object" //true  
  2. typeof "" === "string" //true  
  3. typeof [] === "array"//false 

當(dāng)你對(duì)自己的對(duì)象的實(shí)例使用這個(gè)操作符時(shí)將會(huì)得到相同的結(jié)果(typeof = "object")。

另外說(shuō)明一點(diǎn),”typeof null“將返回”object“,這個(gè)有點(diǎn)詭異。

instanceof

instanceof返回指定對(duì)象是否是由某個(gè)類(lèi)構(gòu)造的實(shí)例,這個(gè)對(duì)我們檢查指定對(duì)象是否是自定義類(lèi)型之一很有幫助,但是,如果你是用文本語(yǔ)法創(chuàng)建的內(nèi)置類(lèi)型那可能會(huì)得出錯(cuò)誤的結(jié)果,代碼如下:

  1. "hello" instanceof String; //false  
  2. new String("hello"instanceof String; //true 

由于Array實(shí)際上不是內(nèi)置類(lèi)型(只是偽裝成內(nèi)置類(lèi)型 - 因此對(duì)它使用typeof不能得到預(yù)期的結(jié)果),但是使用instanceof就能得到預(yù)期效果了,代碼如下所示:

  1. ["item1""item2"instanceof Array;  //true  
  2. new Array("item1""item2"instanceof Array;  //true 

唉,不爽!總的來(lái)說(shuō),如果你想測(cè)試Boolean, String, Number, 或者Function的類(lèi)型,你可以使用typeof,對(duì)于其他的任何類(lèi)型,你可以使用instanceof測(cè)試。

哦,還有一點(diǎn),在一個(gè)function中,有一個(gè)預(yù)定義變量叫“arguments”,它以一個(gè)array的形式傳遞給function。然而,它并不是真正的array,它只是一個(gè)類(lèi)似array的對(duì)象,帶有長(zhǎng)度屬性并且屬性值從0-length。非常奇怪...你可以用下面的小伎倆將它轉(zhuǎn)換成真正的數(shù)組:

  1. var args = Array.prototype.slice.call(arguments, 0); 

這個(gè)對(duì)由getElementsByTagName返回的NodeList對(duì)象也是一樣的 - 它們都可以用以上的代碼轉(zhuǎn)換成合適的數(shù)組。

eval

eval 可以將字符串以javascript代碼的形式來(lái)解析執(zhí)行,但是一般來(lái)說(shuō)我們不建議這么做。因?yàn)閑val非常慢 - 當(dāng)javascript被加載到瀏覽器中時(shí),它會(huì)被編譯成本地代碼;然而執(zhí)行的過(guò)程中每次遇到eval表達(dá)式,編譯引擎都將重新啟動(dòng)執(zhí)行編譯,這樣做的代 價(jià)太大了。而且這樣做也丑陋無(wú)比,有很多eval被濫用的例子。另外,在eval中的代碼會(huì)在當(dāng)前范圍內(nèi)執(zhí)行,因此它可以修改局部變量,以及在你的范圍內(nèi) 添加一些讓你意想不到的東西。

JSON 轉(zhuǎn)換是我們經(jīng)常要做的;通常我們使用“var obj = eval(jsonText);”來(lái)進(jìn)行轉(zhuǎn)換。然而現(xiàn)在幾乎所有的瀏覽器都支持本地JSON對(duì)象,你可以使用“var obj = JSON.parse(jsonText);”來(lái)替代前面的代碼。相反你也可以用“JSON.stringify”將JSON對(duì)象轉(zhuǎn)換成字符串。更妙的 是,你可以使用“jQuery.parseJSON”來(lái)完成上述的工作。

setTimeout和setInterval函數(shù)的第一個(gè)參數(shù)可以用字符串作為函數(shù)體來(lái)解析執(zhí)行,當(dāng)然,我們也不建議這樣做,我們可以用實(shí)際的函數(shù)來(lái)替代。

最后,F(xiàn)unction的構(gòu)造函數(shù)和eval非常像,唯一不同的是,F(xiàn)unction構(gòu)造函數(shù)是在全局范圍內(nèi)執(zhí)行的。

with

with表達(dá)式將為你提供訪問(wèn)對(duì)象屬性的速記方式,但我們是否應(yīng)該使用它,仍然存在矛盾的觀點(diǎn)。Douglas Crockford不太喜歡它。John Resig在他的書(shū)中有找了很多with的巧妙用法,但是他也承認(rèn)這將會(huì)影響性能并且會(huì)產(chǎn)生一點(diǎn)混亂。來(lái)看看我們分離出來(lái)的with代碼塊,他不能準(zhǔn)確地告訴我們現(xiàn)在正在執(zhí)行什么,代碼如下所示:

  1. with (obj) {  
  2.     bob = "mmm";  
  3.     eric = 123;  

我是否剛剛修改了一個(gè)叫bob的局部變量?或者我是否設(shè)置了obj.bob?如果obj.bob已經(jīng)被定義,那么它將會(huì)被重置為“mmm”。否則,如果有 另一個(gè)bob在這個(gè)范圍中,那么他將會(huì)被改變。否則,全局變量bob會(huì)被設(shè)置。最后,下面的寫(xiě)法可以非常明確地表達(dá)你的意思:

  1. obj.bob = "mmm";  
  2. obj.eric = 123; 

ECMAScript5說(shuō)明:ES5嚴(yán)格的來(lái)說(shuō)已經(jīng)不支持with表達(dá)式。

#p#

類(lèi)型和構(gòu)造函數(shù)

使用“new”關(guān)鍵字構(gòu)造內(nèi)置類(lèi)型

Javascript中有Object, Array, Boolean, Number, String, 和Function這些類(lèi)型,他們各自都有各自的文字語(yǔ)法,所以就不需要顯式構(gòu)造函數(shù)了。

顯式構(gòu)造(不建議) 文字語(yǔ)法(推薦)
var a = new Object();
a.greet = "hello";
var a = { greet: "hello" };
var b = new Boolean(true); var b = true;
var c = new Array("one", "two"); var c = ["one", "two"];
var d = new String("hello"); var d = "hello"
var e = new Function("greeting", "alert(greeting);"); var e = function(greeting) { alert(greeting); };

然而,如果你使用new關(guān)鍵字來(lái)構(gòu)造上面其中的一種類(lèi)型,你實(shí)際上將會(huì)得到一個(gè)類(lèi)型為Object并且繼承自你要構(gòu)造的類(lèi)型的原型的對(duì)象(Function類(lèi)型除外)。所以盡管你用new關(guān)鍵字構(gòu)造了一個(gè)Number類(lèi)型,它也將是一個(gè)Object類(lèi)型,如下代碼:

  1. typeof new Number(123); // "object"  
  2. typeof Number(123); // "number"  
  3. typeof 123; // "number" 

上面的第三項(xiàng)是文本語(yǔ)法,為了避免沖突,我們應(yīng)該使用這種方法來(lái)構(gòu)造上面的這些類(lèi)型。

使用“new”關(guān)鍵字來(lái)構(gòu)造任何東西

如果你自寫(xiě)構(gòu)造函數(shù)并且忘記了new關(guān)鍵字,那么悲劇就發(fā)生了:

  1. var Car = function(colour) {  
  2.     this.colour = colour;  
  3. };  
  4.    
  5. var aCar = new Car("blue");  
  6. console.log(aCar.colour); // "blue"  
  7.    
  8. var bCar = Car("blue");  
  9. console.log(bCar.colour); // error  
  10. console.log(window.colour); //"blue" 

使用new關(guān)鍵字調(diào)用函數(shù)會(huì)創(chuàng)建一個(gè)新的對(duì)象,然后調(diào)用新對(duì)象上下文中的函數(shù),最后再返回該對(duì)象。相反的,如果不使用new關(guān)鍵在調(diào)用函數(shù),那它將會(huì)變成一個(gè)全局對(duì)象。

偶然忘記使用new關(guān)鍵字意味著很多可選擇的對(duì)象構(gòu)造模式已經(jīng)出現(xiàn)可以完全刪除使用這個(gè)關(guān)鍵字的需求的情況,盡管這超出了本文的范圍,但我還是建議你去進(jìn)一步閱讀。

沒(méi)有Integer類(lèi)型

數(shù)值計(jì)算是相對(duì)緩慢的,因?yàn)闆](méi)有Integer類(lèi)型。只有Number類(lèi)型 - Number是IEEE標(biāo)準(zhǔn)中雙精度浮點(diǎn)運(yùn)算(64位)類(lèi)型。這就意味著Number會(huì)引起下面的精度舍入錯(cuò)誤:

  1. 0.1 + 0.2 === 0.3 //false 

因?yàn)閕ntegers和floats沒(méi)有區(qū)別,不像C#和JAVA下面代碼是true:

  1. 0.0 === 0; //true 

最后是一個(gè)關(guān)于Number的疑問(wèn),我們?cè)撊绾螌?shí)現(xiàn)下面的問(wèn)題:

  1. a === b; //true  
  2. 1/a === 1/b; //false 

答案是按照Number的規(guī)范是允許出現(xiàn)+0和-0的,+0等于-0,但是正無(wú)窮大不等于負(fù)無(wú)窮大,代碼如下:

  1. var a = 0 * 1; // 這個(gè)結(jié)果為0  
  2. var b = 0 * -1; // 這個(gè)結(jié)果為-0 (你也可以直接"b=-0",但是你為何要這樣做?)  
  3. a === b; //true: 0等于-0  
  4. 1/a === 1/b; //false: 正無(wú)窮大不等于負(fù)無(wú)窮大 

作用域

沒(méi)有塊作用域

因?yàn)槟憧赡芤呀?jīng)注意到上一個(gè)觀點(diǎn),javascript中沒(méi)有塊作用域的概念,只有函數(shù)作用域??梢栽囋囅旅娴拇a:

  1. for(var i=0; i<10; i++) {  
  2.     console.log(i);  
  3. }  
  4. var i;  
  5. console.log(i); // 10 

當(dāng)i被定義在for循環(huán)中,退出循環(huán)后它人被保留在這個(gè)作用域內(nèi),所以最后調(diào)用console.log輸出了10。這里有一個(gè)JSLint警告來(lái)讓你避免這個(gè)問(wèn)題:強(qiáng)制將所有的變量定義在函數(shù)的開(kāi)頭。 我們有可能通過(guò)寫(xiě)一個(gè)立即執(zhí)行的function來(lái)創(chuàng)建一個(gè)作用域:

  1. (function (){  
  2.     for(var i=0; i<10; i++) {  
  3.         console.log(i);  
  4.     }  
  5. }());  
  6. var i;  
  7. console.log(i); // undefined 

當(dāng)你在內(nèi)部函數(shù)之前聲明一個(gè)變量,然后在函數(shù)里重聲明這個(gè)變量,那將會(huì)出現(xiàn)一個(gè)奇怪的問(wèn)題,示例代碼如下:

  1. var x = 3;  
  2. (function (){  
  3.     console.log(x + 2); // 5  
  4.     x = 0; //No var declaration  
  5. }()); 

但是,如果你在內(nèi)部函數(shù)中重新聲明x變量,會(huì)出現(xiàn)一個(gè)奇怪的問(wèn)題:

  1. var x = 3;  
  2. (function (){  
  3.     console.log(x + 2); //NaN - x is not defined  
  4.     var x = 0; //var declaration  
  5. }()); 

這是因?yàn)樵诤瘮?shù)中x變量被重新定義了,這說(shuō)明了翻譯程序?qū)ar表達(dá)式移動(dòng)到了函數(shù)頂部了,最終就變成這樣執(zhí)行了:

  1. var x = 3;  
  2. (function (){  
  3.     var x;  
  4.     console.log(x + 2); //NaN - x is not defined  
  5.     x = 0;  
  6. }()); 

這個(gè)實(shí)在是太有意義了!

全局變量

Javascript 有一個(gè)全局作用域,在為你的代碼創(chuàng)建命名空間時(shí)一定要小心謹(jǐn)慎。全局變量會(huì)給你的應(yīng)用增加一些性能問(wèn)題,因?yàn)楫?dāng)你訪問(wèn)它們時(shí),運(yùn)行時(shí)不得不通過(guò)每一個(gè)作用 域來(lái)建立知道找到它們?yōu)橹?。他們?huì)因你的有意或者無(wú)意而被訪問(wèn)或者修改,這將導(dǎo)致另外一個(gè)更加嚴(yán)重的問(wèn)題 - 跨站點(diǎn)腳本攻擊。如果一個(gè)不懷好意的家伙在你的頁(yè)面上找出了如何執(zhí)行那些代碼的方法,那么他們就可以通過(guò)修改全局變量非常容易地?cái)_亂你的應(yīng)用。缺乏經(jīng)驗(yàn)的 開(kāi)發(fā)者在無(wú)意中會(huì)不斷的將變量添加到全局作用域中,通過(guò)本文,將會(huì)告訴大家這樣會(huì)發(fā)生什么意外的事情。

我曾經(jīng)看到過(guò)下面的代碼,它將嘗試聲明兩個(gè)值相等的局部變量:

  1. var a = b = 3; 

這樣非常正確的得到了a=3和b=3,但是a在局部作用域中而b在全局作用域中,”b=3“將會(huì)被先執(zhí)行,全局操作的結(jié)果,3,再被分配給局部變量a。

下面的代碼聲明了兩個(gè)值為3的變量,這樣能達(dá)到預(yù)期的效果:

  1. var a = 3,  
  2. b = a; 

“this”和內(nèi)部函數(shù)

“this“關(guān)鍵字通常指當(dāng)前正在執(zhí)行的函數(shù)所在的對(duì)象,然而,如果函數(shù)并沒(méi)有在對(duì)象上被調(diào)用,比如在內(nèi)部函數(shù)中,”this“就被設(shè)置為全局對(duì)象(window),如下代碼:

  1. var obj = {  
  2.     doSomething: function () {  
  3.         var a = "bob";  
  4.         console.log(this); // 當(dāng)前執(zhí)行的對(duì)象  
  5.         (function () {  
  6.             console.log(this); // window - "this" is reset  
  7.             console.log(a); // "bob" - still in scope  
  8.         }());  
  9.     }  
  10. };  
  11. obj.doSomething(); 

#p#

雜項(xiàng)

數(shù)據(jù)不存在:”null“和”undefined“

有兩種對(duì)象狀態(tài)來(lái)表明數(shù)據(jù)不存在:null和undefined。這會(huì)讓那些從其他編程語(yǔ)言比如C#轉(zhuǎn)過(guò)來(lái)的程序員變得相當(dāng)混亂。也許你會(huì)期望下面的代碼返回true:

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

”a“實(shí)際上是undefined的(盡管你用雙等號(hào)==來(lái)與null比較會(huì)得出true的結(jié)果,但這只是表面上看起來(lái)正確的另一個(gè)錯(cuò)誤)。

如果你想檢查一個(gè)變量是否真的存在值,那你不能用雙等號(hào)==去判斷,要用下面的方法:

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

”哈“,你也許會(huì)說(shuō),既然null和undefined都是false,那么你可以這樣去做:

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

當(dāng)然,0是false,空字符串也是。那么如果這其中一個(gè)是a的正確的值的話,你就要用前者了。那種比較短小的比較方式,適合于比較objects, arrays, 和booleans類(lèi)型。

重定義undefined

非常正確,你可以重定義undefined,因?yàn)樗皇且粋€(gè)保留字:

  1. undefined = "surprise!"

但是,你要通過(guò)給undefined變量分配一個(gè)值或者使用”void“操作符來(lái)取回值(否則這是相當(dāng)沒(méi)用的)。

  1. undefined = void 0; 

這就是為什么jquery腳本庫(kù)的第一行要這樣寫(xiě)了:

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

這個(gè)函數(shù)被調(diào)用時(shí)是傳入一個(gè)參數(shù)的,同時(shí)確保了第二個(gè)參數(shù)”undefined“實(shí)際上是undefined的。

順便說(shuō)一下,你不能重定義null - 但是你可以重定義NaN,Infinity和帶構(gòu)造函數(shù)的內(nèi)置類(lèi)型??梢赃@樣嘗試一下:

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

當(dāng)然,你可以在任何地方用文字語(yǔ)法聲明Array。

可選的分號(hào)

Javascript代碼中分號(hào)是可選的,所以初學(xué)者寫(xiě)代碼就簡(jiǎn)單多了。但是很不幸的是如果忽略了分號(hào)并不會(huì)給任何人帶來(lái)方便。結(jié)果是當(dāng)解釋器遇到錯(cuò)誤時(shí),必須追溯并嘗試去猜測(cè)因?yàn)槟男┓痔?hào)漏寫(xiě)導(dǎo)致的問(wèn)題。

這里有一個(gè)經(jīng)典的例子:

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

上面的代碼并不會(huì)返回一個(gè)對(duì)象,而是返回了undefined - 但是也沒(méi)有錯(cuò)誤拋出。其實(shí)是因?yàn)榉痔?hào)自動(dòng)加到了return語(yǔ)句后面,其他的代碼都是非常正確的,但是就是什么都不執(zhí)行,這就證明了在 javascript中,左花括號(hào)應(yīng)該緊跟這一行而不該換行,這不只是一個(gè)編程風(fēng)格的問(wèn)題。下面的代碼才會(huì)正確返回一個(gè)屬性為a的對(duì)象:

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

NaN

NaN的類(lèi)型是...Number

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

另外NaN和任何東西比較都是false:

  1. NaN === NaN; // false 

因?yàn)镹aN之間是不能比較的,唯一判斷一個(gè)數(shù)字是否為NaN的方法是調(diào)用isNaN方法。

從另一個(gè)方面可以說(shuō)明,我們也可以用函數(shù)isFinite,當(dāng)其中一個(gè)操作數(shù)為NaN或者InFinity時(shí)返回false。

arguments對(duì)象

在一個(gè)函數(shù)中,我們可以引用arguments對(duì)象來(lái)遍歷傳入的參數(shù)列表,第一個(gè)比較怪異的地方是這個(gè)對(duì)象并不是Array,而是一個(gè)類(lèi)似 Array的對(duì)象(有一個(gè)length屬性,其值在0-length-1之間)。為了將其轉(zhuǎn)換成array,我們可以array的splice函數(shù)來(lái)創(chuàng)建 其對(duì)應(yīng)的array數(shù)組:

  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. }()); 

第二個(gè)比較怪異的地方是當(dāng)一個(gè)函數(shù)的簽名中有顯式arguments參數(shù)時(shí),它們是可以被重新分配的并且arguments對(duì)象也會(huì)被改變。這就表明了arguments對(duì)象指向了變量本身。你不能利用arguments對(duì)象來(lái)給出它們的初始值:

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

結(jié)束本文!

這樣我就總結(jié)完了這些javascript陷阱。我肯定還會(huì)有更多這樣的陷阱,期待大家更多的意見(jiàn)和點(diǎn)評(píng)。

PS - 我真的很喜歡Javascript。

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

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

譯者:王國(guó)峰

【編輯推薦】

  1. 使用JavaScript和Canvas寫(xiě)一個(gè)游戲框架
  2. JavaScript將成為計(jì)算機(jī)學(xué)習(xí)第一語(yǔ)言
  3. 編寫(xiě)高質(zhì)量JavaScript代碼的基本要點(diǎn)
  4. 大型JavaScript應(yīng)用程序架構(gòu)模式
  5. 20個(gè)將JavaScript推到極致的網(wǎng)站
責(zé)任編輯:陳貽新 來(lái)源: 王國(guó)峰的博客
相關(guān)推薦

2010-02-03 09:53:08

Python版本

2010-07-14 14:02:52

SQL Server數(shù)

2012-04-28 10:29:24

jQuery

2010-07-26 09:06:09

SQL Server游

2010-02-24 10:52:24

IBM中端服務(wù)器

2011-07-04 10:33:22

QT

2010-10-20 17:31:40

Fedora應(yīng)用

2014-05-15 15:29:09

Android開(kāi)發(fā)資源

2013-08-13 13:38:13

Android錯(cuò)誤解決

2011-06-21 10:44:32

QT QTE

2018-12-17 09:00:00

大數(shù)據(jù)數(shù)據(jù)科學(xué)工具

2010-06-09 17:00:43

UML試題

2010-01-27 14:48:55

優(yōu)秀C++編譯器

2009-11-24 19:02:35

PHP常用字符串

2009-08-24 11:04:56

2010-08-04 09:57:28

路由器

2010-10-12 14:28:54

2025-02-17 00:00:03

人工智能AI工具

2009-01-07 10:30:25

2014-06-12 17:02:46

世界杯手游
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)