今天學到了JavaScript的語句篇。同其他常見編程語言如C、Java等一樣,JavaScript中的語句包含:①表達式語句②復合語句和空語句③聲明語句④條件語句⑤循環語句⑥跳轉語句,當然JavaScript還有⑦其他三種語句。那么標題叫做JavaScript循環之for/in循環,主要是因為我覺得這里面大多語句跟C、Java那些一樣,沒必要再浪費口舌介紹了,但for/in循環是第一次在JavaScript中接觸的。當然,這些都是非常基礎的內容,只是做為學習筆記,初學JavaScript可以看看,熟練掌握的就不必再浪費時間閱讀了。
首先,先說下稍微有點特殊性的空語句吧。空語句只有一個分號即: ; ,很簡單,令人不禁要想有毛用? 。曾經聽說過:世界上任何事物如果存在,必有它存在的原因。空語句也不例外,它還是有點作用滴。JavaScript解釋器執行空語句時它顯然不會執行任何動作。但實踐證明,當創建一個具有空循環體的循環時,空語句有時很有用。例如:
//初始化一個數組a
for(var i=0; i<a.length; a[i++]=0) ;
在這個循環中,所有操作都在表達式a[i++]=0中完成,並不需要任何循環體,然而JavaScript需要循環體中至少要包含一條語句,因此這里用了空語句。當然這個也可以用while循環實現,只是這個簡潔了點而已。
空語句目測也就那點作用了。至於JavaScript中的聲明語句,那肯定得詳細說說變量聲明提前特性了啊,這是JavaScript的一個重點啊,很抱歉這里就不詳說了,如果想要了解,請點擊:http://www.cnblogs.com/craftsman-gao/p/4720635.html 。條件語句中,if 和else if 也都跟C、Java一樣,就不多廢話了,switch 語句倒是有一個容易忽略的知識點。當執行switch語句時,首先計算switch后括號中的表達式的值,然后查找case子句的表達式的值是否和switch后面括號中表達式的值相同,來進行匹配,重點是:這里比較兩個表達式的值是否相同時使用的是完全相等,即"===" 。
好了,現在到真正要說的循環語句了。JavaScript中的循環有四種,:while、do/while、for 和 for/in。前三種也是沒啥特點,所以就直接說for/in了。先看其語法:
1 for(variable in object) 2 statement
variable通常是一個變量名,也可以是一個可以產生左值的表達式或者一個通過var 語句聲明的變量,總之必須是一個適合用於賦值表達式左側的值。object是一個表達式,這個表達式的計算結果是一個對象。同樣,statement 是一個語句或語句塊,它構成了循環的主體。使用for/in循環可以很方便的遍歷對象屬性成員:
1 for(var p in o) 2 console.log(o[p]);
在執行for/in語句過程中,JavaScript解釋器首先計算object表達式。如果表達式為null 或者 undefined , JavaScript解釋器將會跳過循環並執行后續代碼。如果表達式等於一個原始值,這個原始值將會轉換成與之對應的包裝對象。否則,表達式本身已經是對象了。JavaScript會依次枚舉對象的屬性來執行循環。在每次循環之前,JavaScript都會將對象的一個屬性名(一個字符串)賦值給variable。
需要注意的是,只要for/in循環中variable的值可以當做賦值表達式的左值,它可以是任意表達式。例如,可以使用下面這段代碼把所用對象屬性復制到一個數組中:
1 var o = {x:1, y:2, z:3}; 2 var a =[], i=0; 3 for(a[i++] in o) ;//注意這里就用了空語句
因為,JavaScript數組是一種特殊的對象,因此,for/in循環可以像枚舉對象屬性一樣枚舉數組索引。例如:
1 for(var i in arr) 2 console.log(i);//依次輸出數組的索引值
注意:for/in循環並不會遍歷對象的所有屬性,只有“可枚舉(enumerable)”的屬性才會遍歷到(這一點是對象的內容了,以后再做詳說吧)。由JavaScript語言核心所定義的內置方法就不是“可枚舉的”。比如,所有的對象都有方法toString(),但for/in循環並不枚舉toString這個屬性。除了內置方法之外,還有很多內置對象的屬性也是“不可枚舉的“。而代碼中定義的所有屬性和方法是可枚舉的。對象可以繼承其他對象的屬性,那些繼承的自定義屬性也可以使用for/in枚舉出來。關於屬性枚舉的順序,ECMAScript規范並沒有指定,主流瀏覽器廠商的JavaScript實現是按照屬性定義的先后順序來枚舉簡單對象的屬性,先定義的屬性先枚舉。如果使用對象直接量的形式創建對象,則將按照直接量中屬性出現順序枚舉。
還有兩點需要注意:a.如果for/in的循環體刪除了還未枚舉的屬性,那么這個屬性將不會再枚舉到;b.如果循環體定義了對象的新屬性,這些屬性通常也不會枚舉到;
另外的三種語句就是:①with②debugger(用於調試程序時給程序打斷點)③"use strict"。不過這里先暫且不說這三個了。
[新增(2105.09.07)]今天在寫比較兩個對象的各個屬性值是否完全相同時,發現for/in循環中,調用對象屬性值只能使用[]運算符,並不能使用.運算符,不管是在遍歷數組還是普通對象。又算是學習路上發現的一坑吧,這里記錄下。
[新增(2105.09.011)]在使用for/in循環遍歷對象的屬性時。對象的hasOwnProperty()方法用來檢測給定的名字是否是對象的自有屬性,對於繼承屬性它將返回false,例如:。
1 var o = {x:1}; 2 o.hasOwnProperty('x'); //true: 對象o有一個自有屬性x 3 o.hasOwnProperty('y'); //false:對象o不存在屬性y 4 o.hasOwnProperty('toString'); //false:toString是繼承屬性