《JavaScript權威指南》讀書筆記3 語句

for/in循環(huán)

這是C/C++語言沒有的便捷語法,Java支持for/in视卢,不過JavaScript語法稍有不同演训。

for(variable in object) {
    statement
}

for/in循環(huán)常用來遍歷對象屬性成員:

for(var p in o)   //將屬性名字賦值給變量p
    console.log(o[p]);   //輸出每一個屬性的值

在執(zhí)行for/in語句的過程中锁右,JavaScript解釋器首先計算object表達式。如果表達式為null或者undefined哎壳,JavaScirpt解釋器將會跳過循環(huán)并執(zhí)行后續(xù)的代碼。如果表達式等于一個原始值尚卫,這個原始值將會轉換為與之對應的包裝對象(wrapper object)JavaScript會依次枚舉對象的屬性來執(zhí)行循環(huán)归榕,每次循環(huán)之前,JavaScript都會先計算variable表達式的值吱涉,并將屬性名(一個字符串)賦值給它刹泄。

只要for/in循環(huán)中variable的值可以當做賦值表達式的左值,它可以是任意表達式怎爵。每次循環(huán)都會計算這個表達式特石,也就是說每次循環(huán)它計算的值有可能不同。例如鳖链,可以使用下面這段代碼將所有對象屬性復制至一個數(shù)組中:

var o = {x:1, y:2, z:3};
var a = [], i = 0;
for (a[i++] in o) /*empty*/ ;

JavaScript數(shù)組不過是一種特殊的對象姆蘸,因此,for/in循環(huán)可以像枚舉對象屬性一樣枚舉數(shù)組索引。例如逞敷,在上面的代碼之后加上這段代碼就可以枚舉數(shù)組的索引0狂秦、1、2:for(i in a)console.log(i);

for/in循環(huán)并不會遍歷對象的所有屬性推捐,只有“可枚舉”(enumerable)的屬性才會遍歷到裂问。由JavaScript語言核心所定義的內置方法就不是“可枚舉的”,比如玖姑,所有的對象都有方法toString()愕秫,但for/in循環(huán)并不枚舉toString這個屬性。除了內置方法之外焰络,還有很多內置對象的屬性也是“不可枚舉的”(nonenumerable)戴甩。而代碼中定義的所有屬性和方法都是可枚舉的,當然也可以使用Object.defineProperty()定義為不可枚舉的屬性闪彼。

標簽語句

語句是可以添加標簽的甜孤,標簽是由語句前的標識符和冒號組成:

identifer: statement

break和continue是JavaScript中唯一可以使用語句標簽的語句。

mainloop: while (token != null) {
    //忽略這里的代碼...
    if (condition1) continue mainloop; //跳轉到下一次循環(huán)
    //忽略這里的代碼...
    if (condition2) break mainloop;  //結束這個循環(huán)代碼段
    //忽略這里的代碼...
}

標簽語句盡量少用畏腕,與C/C++中的標簽語句類似缴川,除非在減少出口讓邏輯變得更簡單的情況下使用,否則描馅,這總歸是代碼不優(yōu)雅的表現(xiàn)把夸!

with語句

這還是很多年前使用Delphi用到的語法了,不過在JavaScript中嚴格模式下是禁用with語句的铭污,非嚴格模式里實際上也不推薦使用恋日,了解含義即可。with語句用于臨時拓展作用域嘹狞,比如下面訪問HTML表單中的元素:

document.forms[0].name.value
document.forms[0].address.value
document.forms[0].email.value

如果這種表達式在代碼中多次出現(xiàn)岂膳,則可以使用with語句將form對象添加至作用域鏈的頂層:

with (document.forms[0]) {
    name.value = "";
    address.value = "";
    email.value = "";
}

debugger語句

debugger語句通常什么也不做,但當調試程序可用并運行的時候磅网,JavaScript解釋器將會以調式模式運行谈截。這條語句用來產生一個斷點(breakpoint),JavaScript代碼的執(zhí)行會停止在斷點的位置涧偷,這時可以使用調試器輸出變量的值簸喂、檢查調用棧等。例如嫂丙,假設由于調用函數(shù)f()的時候使用了未定義的參數(shù)娘赴,因此f()拋出一個異常,但無法定位到底是哪里拋出了異常跟啤。為了有助于調試這個問題诽表,需要修改函數(shù)f():

function f(o) {
    if (o === undefined) debugger;  //這一行代碼只是用于臨時調試
    ...  //函數(shù)的其他部分
}

"use strict"

使用"use strict"指令的目的是說明(腳本或函數(shù)中)后續(xù)的代碼將會解析為嚴格代碼(strict code)唉锌。如果頂層(不在任何函數(shù)內的)代碼使用了"use strict"指令,那么它們就是嚴格代碼竿奏。如果函數(shù)體定義所處的代碼是嚴格代碼或者函數(shù)體使用了"use strict"指令袄简,那么函數(shù)體的代碼也是嚴格代碼。如果eval()調用時所處的代碼是嚴格代碼或者eval()要執(zhí)行的字符串中使用了"scrict code"指令泛啸,則eval()內的代碼是嚴格代碼绿语。

嚴格模式和非嚴格模式之間的區(qū)別如下(前三條尤為重要):

  • 在嚴格模式中禁止使用with語句。
  • 在嚴格模式中候址,所有的變量都要先聲明吕粹,如果給一個未聲明的變量、函數(shù)岗仑、函數(shù)參數(shù)匹耕、catch從句參數(shù)或全局對象的屬性賦值,將會拋出一個引用錯誤異常(在非嚴格模式中荠雕,這種隱式聲明的全局變量的方法是給全局對象新添加一個新屬性)稳其。
  • 在嚴格模式中,調用的函數(shù)中的this值是undefined炸卑,(在非嚴格模式中既鞠,調用的函數(shù)中的this值總是全局對象),可以利用這種特性來判斷JavaScript實現(xiàn)是否支持嚴格模式:var hasStrictMode=(function(){"use strict";return this===undefined}());盖文。
  • 同樣嘱蛋,在嚴格模式中,當通過call()或apply()來調用函數(shù)時五续,其中的this值就是通過call()或apply()傳入的第一個參數(shù)(在非嚴格模式中浑槽,null和undefined值被全局對象和轉換為對象的非對象值所代替)。
  • 在嚴格模式中返帕,給只讀屬性賦值和給不可擴展的對象創(chuàng)建新成員都將拋出一個類型錯誤異常(在非嚴格模式中,這些操作只是簡單地操作失敗篙挽,不會報錯)荆萤。
  • 在嚴格模式中,傳入eval()的代碼不能在調用程序所在的上下文中聲明變量或定義函數(shù)铣卡,而在非嚴格模式中是可以這樣做的链韭。相反,變量和函數(shù)的定義是在eval()創(chuàng)建的新作用域中煮落,這個作用域在eval()返回時就棄用了敞峭。
  • 在嚴格模式中,函數(shù)里的arguments對象擁有傳入函數(shù)值的靜態(tài)副本蝉仇。在非嚴格模式中旋讹,arguments對象具有“魔術般”的行為殖蚕,arguments里的數(shù)組元素和函數(shù)參數(shù)都是指向同一個值的引用。
  • 在嚴格模式中沉迹,當delete運算符后跟隨非法的標識符(比如變量睦疫、函數(shù)、函數(shù)參數(shù))時鞭呕,將會拋出一個語法錯誤異常(在非嚴格模式中蛤育,這種delete表達式什么也沒做,并返回false)葫松。
  • 在嚴格模式中瓦糕,試圖刪除一個不可配置的屬性將拋出一個類型錯誤異常(在非嚴格模式中,delete表達式操作失敗腋么,并返回false)咕娄。
  • 在嚴格模式中,在一個對象直接量中定義兩個或多個同名屬性將產生一個語法錯誤(在非嚴格模式中不會報錯)党晋。
  • 在嚴格模式中谭胚,函數(shù)聲明中存在兩個或多個同名的參數(shù)將產生一個語法錯誤(在非嚴格模式中不會報錯)。
  • 在嚴格模式中是不允許使用八進制整數(shù)直接量(以0為前綴未玻,而不是0x為前綴)的(在非嚴格模式中某些實現(xiàn)是允許八進制整數(shù)直接量的)灾而。
  • 在嚴格模式中,標識符eval和arguments當做關鍵字扳剿,它們的值是不能更改的旁趟。不能給這些標識符賦值,也不能把它們聲明為變量庇绽、用做函數(shù)名锡搜、用做函數(shù)參數(shù)或用做catch塊的標識符。
  • 在嚴格模式中限制了對調用棧的檢測能力瞧掺,在嚴格模式的函數(shù)中耕餐,arguments.caller和arguments.callee都會拋出一個類型錯誤異常。嚴格模式的函數(shù)同樣具有caller和arguments屬性辟狈,當訪問這兩個屬性時將拋出類型錯誤異常(有一些JavaScript的實現(xiàn)在非嚴格模式里定義了這些非標準的屬性)肠缔。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哼转,隨后出現(xiàn)的幾起案子明未,更是在濱河造成了極大的恐慌,老刑警劉巖壹蔓,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趟妥,死亡現(xiàn)場離奇詭異,居然都是意外死亡佣蓉,警方通過查閱死者的電腦和手機披摄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門亲雪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人行疏,你說我怎么就攤上這事匆光。” “怎么了酿联?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵终息,是天一觀的道長。 經常有香客問我贞让,道長周崭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任喳张,我火速辦了婚禮续镇,結果婚禮上,老公的妹妹穿的比我還像新娘销部。我一直安慰自己摸航,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布舅桩。 她就那樣靜靜地躺著酱虎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪擂涛。 梳的紋絲不亂的頭發(fā)上读串,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音撒妈,去河邊找鬼恢暖。 笑死,一個胖子當著我的面吹牛狰右,可吹牛的內容都是我干的杰捂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棋蚌,長吁一口氣:“原來是場噩夢啊……” “哼琼娘!你這毒婦竟也來了?” 一聲冷哼從身側響起附鸽,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞒瘸,沒想到半個月后坷备,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡情臭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年省撑,在試婚紗的時候發(fā)現(xiàn)自己被綠了赌蔑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡竟秫,死狀恐怖娃惯,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情肥败,我是刑警寧澤趾浅,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站馒稍,受9級特大地震影響皿哨,放射性物質發(fā)生泄漏。R本人自食惡果不足惜纽谒,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一证膨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鼓黔,春花似錦央勒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肆捕,卻和暖如春刷晋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背慎陵。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工眼虱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人席纽。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓捏悬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親润梯。 傳聞我的和親對象是個殘疾皇子过牙,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容