【讀書筆記】《JavaScript權威指南》第5章語句

前言

  表達式在JavaScript中是短語,那麼語句(statement)就是JavaScript整句或命令。表達式計算出一個值,但語句用來執行以使某件事發生
  “使某件事發生”的一個方法是計算帶有副作用的表達式。諸如賦值和函數調用這些有副作用的表達式,是可以作爲單獨的語句的,這種把表達式當做語句的用法也稱做表達式語句(expression statement)。類似的語句還有聲明語句(declaration statement),聲明語句用來聲明新變量或定義新函數。
  另一種“使某件事發生”的方法是改變語句的默認執行順序。默認情況下,JavaScript解釋器依照語句的編寫順序依次執行。JavaScript中有很多語句和控制結構(control structure)來改變語句的默認執行順序:

  • 條件(conditional)語句,JavaScript解釋器可以根據一個表達式的值來判斷是執行還是跳過這些語句,如if語句和switch語句。
  • 循環(loop)語句,可以重複執行語句,如while和for語句。
  • 跳轉(jump)語句,可以讓解釋器跳轉至程序的其他部分繼續執行,如break、return和throw語句

表達式語句(掌握)

  具有副作用的表達式是JavaScript中最簡單的語句。賦值語句是一類比較重要的表達式語句,例如:

greeting="Hello"+name;
i*=3;

  遞增運算符(++)和遞減運算符(--)和賦值語句有關。它們的作用是改變一個變量的值,就像執行一條賦值語句一樣:

counter++;

  delete運算符的重要作用是刪除一個對象的屬性,所以,它一般作爲語句使用,而不是作爲複雜表達式的一部分:

delete o.x;

  函數調用是表達式語句的另一個大類,例如:

alert(greeting);
window.close();

複合語句和空語句(掌握)

  JavaScript中還可以將多條語句聯合在一起,形成一條複合語句(compound statement)。只須用花括號將多條語句括起來即可。因此,下面幾行代碼就可以當成一條單獨的語句,使用在JavaScript中任何希望使用一條語句的地方:

{
    x=Math.PI;
    cx=Math.cos(x);
    console.1og("cos(π)="+cx);
}
  • 第一,語句塊的結尾不需要分號。塊中的原始語句必須以分號結束,但語句塊不需要。
  • 第二,語句塊中的行都有縮進,這不是必需的,但整齊的縮進能讓代碼可讀性更強,更容易理解。
  • 最後,需要注意,JavaScript中沒有塊級作用域,在語句塊中聲明的變量並不是語句塊私有的。
//初始化一個數組a
for(i=0;i<a.length;a[i++]=0);

  在這個循環中,所有的操作都在表達式a[i++]=0中完成,這裏並不需要任何循環體。然而JavaScript需要循環體中至少包含一條語句,因此,這裏只使用了一個單獨的分號來表示一條空語句。
  注意,在for循環、while循環或if語句的右圓括號後的分號很不起眼,這很可能造成一些致命bug,而這些bug很難定位到。例如,下面的代碼的執行結果可能就不是程序作者想要的效果:

if((a==0)||(b==0));//糟糕!這一行代碼什麼都沒做...
a=nul1;/這一行代碼總是會執行

  如果有特殊的目的需要使用空語句,最好在代碼中添加註釋,這樣可以更清楚地說明這條空語句是有用的,例如:

for(i=o;i<a.length;a[i++]=0)/*empty*/;

聲明語句(掌握)

var

  var語句用來聲明一個或者多個變量,var聲明的變量是無法通過delete刪除的。
  如果var語句中的變量沒有指定初始化表達式,那麼這個變量的值初始爲undefined。
  變量在聲明它們的腳本或函數中都是有定義的,變量聲明語句會被“提前”至腳本或者函數的頂部。但是初始化的操作則還在原來var語句的位置執行,在聲明語句之前變量的值是undefined。
  需要注意的是,var語句同樣可以作爲for循環或者for/in循環的組成部分(和在循環之外聲明的變量聲明一樣,這裏聲明的變量也會“提前”)。

function

  function是要聲明的函數的名稱的標識符。函數名之後的圓括號中是參數列表,參數之間使用逗號分隔。當調用函數時,這些標識符則指代傳入函數的實參。
  函數體是由JavaScript語句組成的,語句的數量不限,且用花括號括起來。在定義函數時,並不執行函數體內的語句,它和調用函數時待執行的新函數對象相關聯。注意,function語句裏的花括號是必需的,這和while循環和其他一些語句所使用的語句塊是不同的,即使函數體只包含一條語句,仍然必須使用花括號將其括起來。
  函數聲明語句通常出現在JavaScript代碼的最頂層,也可以嵌套在其他函數體內。但在嵌套時,函數聲明只能出現在所嵌套函數的頂部。也就是說,函數定義不能出現在if語句、while循環或其他任何語句中,正是由於函數聲明位置的這種限制,ECMAScript標準規範並沒有將函數聲明歸類爲真正的語句。有一些JavaScript實現的確允許在出現語句的地方都可以進行函數聲明,但是不同的實現在細節處理方式上有很大差別,因此將函數聲明放在其他的語句內的做法並不具備可移植性。
  和通過var聲明變量一樣,函數定義語句中的函數被顯式地“提前”到了腳本或函數的頂部。因此它們在整個腳本和函數內都是可見的。使用var的話,只有變量聲明提前了——變量的初始化代碼仍然在原來的位置。然而使用函數聲明語句的話,函數名稱和函數體均提前:腳本中的所有函數和函數中所有嵌套的函數都會在當前上下文中其他代碼之前聲明。也就是說,可以在聲明一個JavaScript函數之前調用它。
  和var語句一樣,函數聲明語句創建的變量也是無法刪除的。但是這些變量不是隻讀的,變量值可以重寫。

條件語句(掌握)

  條件語句是通過判斷指定表達式的值來決定執行還是跳過某些語句。這些語句是代碼的
“決策點”,有時稱爲“分支”。如果說JavaScript解釋器是按照代碼的“路徑”執行的,條件語句就是這條路徑上的分叉點,程序執行到這裏時必須選擇其中一條路徑繼續執行。

if

  需要注意的是,if語句中括住expression的圓括號在語法上是必需的。JavaScript語法規定,if關鍵字和帶圓括號的表達式之後必須跟隨一條語句,但可以使用語句塊將多條語句合併成一條。

else if

  if/e1se語句通過判斷一個表達式的計算結果來選擇執行兩條分支中的一條。但當代碼中有多條分支的時候該怎麼辦呢?一種解決辦法是使用else if語句。elseif語句並不是真正的JavaScript語句,它只不過是多條if/else語句連在一起時的一種慣用寫法。

switch

  當所有的分支都依賴於同一個表達式的值時,else if並不是最佳解決方案。在這種情況下,重複計算多條if語句中的條件表達式是非常浪費的做法。
  switch語句正適合處理這種情況。關鍵字switch之後緊跟着圓括號括起來的一個表達式,隨後是一對花括號括起來的代碼塊:

switch(expression){
statements
}

  然而,switch語句的完整語法要比這複雜一些。代碼塊中可以使用多個由case關鍵字標識的代碼片段,case之後是一個表達式和一個冒號,case和標記語句很類似,只是這個標記語句並沒有名字,它只和它後面的表達式關聯在一起。當執行這條switch語句的時候,它首先計算expression的值,然後查找case子句中的表達式是否和expression的值相同(這裏的“相同”是按照“===”運算符進行比較的)。如果找到匹配的case,那麼將會執行這個case對應的代碼塊。如果找不到匹配的case,那麼將會執行“default:”標籤中的代碼塊。如果沒有“default:”標籤,switch語句將跳過它的所有代碼塊。

switch(n){
    case 1://如果n===1,從這裏開始執行
    //執行代碼塊1
    break;//停止執行switch語句
    case 2://如果n===2,從這裏執行
    //執行代碼塊2
    break;//在這裏停止執行switch語句
    case 3://如果n===3,從這裏執行
    //執行代碼塊3
    break;//在這裏停止執行switch語句
    default://如果所有的條件都不匹配
    //執行代碼塊4
    break;//在這裏停止執行switch語句
}

  如果沒有break語句,那麼switch語句就會從與expression的值相匹配的case標籤處的代碼塊開始執行,依次執行後續的語句,一直到整個switch代碼塊的結尾。如果在函數中使用switch語句,可以使用return來代替break,return和break都用於終止switch語句,也會防止一個case語句塊執行完後繼續執行下一個case語句塊。

循環(掌握)

while

while(expression)
    statement

  在執行while語句之前,JavaScript解釋器首先計算expression的值,如果它的值是假值,那麼程序將跳過循環體中的邏輯statement轉而執行程序中的下一條語句。反之,如果表達式expression是真值,JavaScript解釋器將執行循環體內的邏輯,然後再次計算表達式expression的值,這種循環會一直繼續下去,直到expression的值爲假值爲止。

do/while

  do/while循環和while循環非常相似,只不過它是在循環的尾部而不是頂部檢測循環表達式,這就意味着循環體至少會執行一次。do/while循環的語法如下:

do
    statement
while(expression);
do{
    console.1og(a[i]);
}while(++i<len);

  在do/while循環和普通的while循環之間有兩點語法方面的不同之處。
  首先,do循環要求必須使用關鍵字do來標識循環的開始,用while來標識循環的結尾並進入循環條件判斷。
  其次,和while循環不同,do循環是用分號結尾的。如果while的循環體使用花括號括起來的話,則while循環也不用使用分號做結尾。

for

for(initialize;test;increment)
    statement

  當然,有些循環會比這些例子更加複雜,而且循環中的一次迭代會改變多個變量。在JavaScript中,這種情況則必須用到逗號運算符,它將初始化表達式和自增表達式合併入一個表達式中以用於for循環:

var i,j;
for(i=0,j=10;i<10;i++,j--)
    sum+=i*j;

for/in

for(variable in object)
    statement

  在執行for/in語句的過程中,JavaScript解釋器首先計算object表達式。如果表達式爲nu11或者undefined,JavaScirpt解釋器將會跳過循環並執行後續的代碼。如果表達式等於一個原始值,這個原始值將會轉換爲與之對應的包裝對象(wrapper object)(見3.6節)。否則,expression本身已經是對象了。JavaScript會依次枚舉對象的屬性來執行循環。然而在每次循環之前,JavaScript都會先計算variable表達式的值,並將屬性名(一個字符串)賦值給它。

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

  其實,for/in循環並不會遍歷對象的所有屬性,只有“可枚舉”(enumerable)的屬性纔會遍歷到。由JavaScript語言核心所定義的內置方法就不是“可枚舉的”。比如,所有的對象都有方法toString(),但for/in循環並不枚舉toString這個屬性。除了內置方法之外,還有很多內置對象的屬性也是“不可枚舉的”(nonenumerable)。
  而代碼中定義的所有屬性和方法都是可枚舉的。對象可以繼承其他對象的屬性,那些繼承的自定義屬性也可以使用for/in枚舉出來。
  如果for/in的循環體刪除了還未枚舉的屬性,那麼這個屬性將不會再枚舉到。
  如果循環體定義了對象的新屬性,這些屬性通常也不會枚舉到(然而,JavaScript的有些實現是可以枚舉那些在循環體中增加的繼承屬性的)。

屬性枚舉的順序

  ECMAScript規範並沒有指定for/in循環按照何種順序來枚舉對象屬性。但實際上,主流瀏覽器廠商的JavaScript實現是按照屬性定義的先後順序來枚舉簡單對象的屬性,先定義的屬性先枚舉。
  在下列情況下,枚舉的順序取決於具體的實現(並且是非交互的):

  • 對象繼承了可枚舉屬性;
  • 對象具有整數數組索引的屬性;
  • 使用delete刪除了對象已有的屬性;
  • 使用Object.defineProperty()或者類似的方法改變了對象的屬性。

  但當數組元素的索引是非數字或數組是稀疏數組(數組索引是不連續的)時它們則按照特定順序枚舉。

跳轉(掌握)

標籤語句

  語句是可以添加標籤的,標籤是由語句前的標識符和冒號組成。break和continue是JavaScript中唯一可以使用語句標籤的語句。

mainloop:while(tokenl=nul1){
    //忽略這裏的代碼..
    continue mainloop;//跳轉到下一次循環
    //忽略這裏的代碼…
}

  這裏用做標籤的identifier必須是一個合法的JavaScript標識符,而不能是一個保留字。標籤的命名空間和變量或函數的命名空間是不同的,因此可以使用同一個標識符作爲語句標籤和作爲變量名或函數名。
  語句標籤只有在它所起作用的語句(當然也可以在它的子句中)內是有定義的。一個語句標籤不能和它內部的語句標籤重名,但在兩個代碼段不相互嵌套的情況下是可以出現同名的語句標籤的。帶有標籤的語句還可以帶有標籤,也就是說,任何語句可以有很多個標籤。

break 語句

  單獨使用break語句的作用是立即退出最內層的循環或switch語句。
  在break關鍵字和labelname之間不能換行。因爲JavaScript可以給語句自動補全省略掉的分號,如果break關鍵字和標籤之間有換行,JavaScript解釋器會認爲你在使用break不帶標籤的最簡形式,因此會在break後補充分號。
  最後,需要注意的是,不管break語句帶不帶標籤,它的控制權都無法越過函數的邊界。比如,對於一條帶標籤的函數定義語句來說,不能從函數內部通過這個標籤來跳轉到函數外部。

continue 語句

  continue語句和break語句非常類似,但它不是退出循環,而是轉而執行下一次循環。不管continue語句帶不帶標籤,它只能在循環體內使用。在其他地方使用將會報語法錯誤。
  在不同類型的循環中,continue的行爲也有所區別:

  • 在while循環中,在循環開始處指定的expression會重複檢測,如果檢測結果爲true,循環體會從頭開始執行。
  • 在do/while循環中,程序的執行直接跳到循環結尾處,這時會重新判斷循環條件,之後纔會繼續下一次循環。
  • 在for循環中,首先計算自增表達式,然後再次檢測test表達式,用以判斷是否執行循環體。
  • 在for/in循環中,循環開始遍歷下一個屬性名,這個屬性名賦給了指定的變量。

  需要注意continue語句在while和for循環中的區別,while循環直接進入下一輪的循環條件判斷,但for循環首先計算其increment表達式,然後判斷循環條件。

return 語句

  函數中的return語句既是指定函數調用後的返回值。return語句只能在函數體內出現,如果不是的話會報語法錯誤。當執行到return語句的時候,函數終止執行,並返回expression的值給調用程序。
  由於JavaScript可以自動插入分號,因此在return關鍵字和它後面的表達式之間不能有換行。

throw 語句

  所謂異常(exception)是當發生了某種異常情況或錯誤時產生的一個信號。拋出異常,就是用信號通知發生了錯誤或異常狀況。捕獲異常是指處理這個信號,即採取必要的手段從異常中恢復。在JavaScript中,當產生運行時錯誤或者程序使用throvw語句時就會顯式地拋出異常。使用try/catch/finally語句可以捕獲異常。

throw expression;

  expression的值可以是任意類型的。可以拋出一個代表錯誤碼的數字,或者包含可讀的錯誤消息的字符串。當JavaScript解釋器拋出異常的時候通常採用Error類型和其子類型,當然也可以使用它們。一個Error對象有一個name屬性表示錯誤類型,一個message屬性用來存放傳遞給構造函數的字符串。

function factorial(x){
    //如果輸入參數是非法的,則拋出一個異常
    if(x<0)throw new Error("x不能是負數”);
    //否則,計算出一個值,並正常地返回它
    for(var f=1;x>1;f*=x,x--)/* empty*/;
    return f;
}

  當拋出異常時,JavaScript解釋器會立即停止當前正在執行的邏輯,並跳轉至就近的異常處理程序。異常處理程序是用try/catch/finally語句的catch從句編寫的,下一節會介紹它。
  如果拋出異常的代碼塊沒有一條相關聯的catch從句,解釋器會檢查更高層的閉合代碼塊,看它是否有相關聯的異常處理程序。以此類推,直到找到一個異常處理程序爲止。如果拋出異常的函數沒有處理它的try/catch/finally語句,異常將向上傳播到調用該函數的代碼。這樣的話,異常就會沿着JavaScript方法的詞法結構和調用棧向上傳播。如果沒有找到任何異常處理程序,JavaScript將把異常當成程序錯誤來處理,並報告給用戶。

try/catch/finally語句

  try/catch/finally語句是JavaScript的異常處理機制。其中try從句定義了需要處理的異常所在的代碼塊。catch從句跟隨在try從句之後,當try塊內某處發生了異常時,調用catch內的代碼邏輯。catch從句後跟隨finally塊,後者中放置清理代碼,不管try塊中是否產生異常,finally塊內的邏輯總是會執行。
  儘管catch和finally都是可選的,但try從句需要至少二者之一與之組成完整的語句。try、catch和finally語句塊都需要使用花括號括起來,這裏的花括號是必需的,即使從句中只有一條語句也不能省略花括號。

try{
    //通常來講,這裏的代碼會從頭執行到尾而不會產生任何問題,
    //但有時會拋出一個異常,要麼是由throw語句直接拋出異常,
    //要麼是通過調用一個方法間接拋出異常
catch(e){
    //當且僅當try語句塊拋出了異常,纔會執行這裏的代碼
    //這裏可以通過局部變量e來獲得對Error對象或者拋出的其他值的引用
    //這裏的代碼塊可以基於某種原因處理這個異常,也可以忽略這個異常,
    //還可以通過throw語句重新拋出異常
finally{
    //不管try語句塊是否拋出了異常,這裏的邏輯總是會執行,終止try語句塊的方式有:
    //1)正常終止,執行完語句塊的最後一條語句
    //2)通過break、continue或return語句終止
    //3)拋出一個異常,異常被catch從句捕獲
    //4)拋出一個異常,異常未被捕獲,繼續向上傳播
}

  關鍵字catch後跟隨了一對圓括號,圓括號內是一個標識符。這個標識符具有塊級作用域,它只在catch語句塊內有定義。
  通常狀況下,解釋器執行到try塊的尾部,然後開始執行finally中的邏輯,以便進行必要的清理工作。當由於return、continue或break語句使得解釋器跳出try語句塊時,解釋器在執行新的目標代碼之前先執行fnally塊中的邏輯。
  如果在try中產生了異常,而且存在一條與之相關的catch從句來處理這個異常,解釋器會首先執行catch中的邏輯,然後執行finally中的邏輯。如果不存在處理異常的局部catch從句,解釋器會首先執行finally中的邏輯,然後向上傳播這個異常,直到找到能處理這個異常的catch從句。
  如果finally塊使用了return、continue、break或者throw語句使程序發生跳轉,或者通過調用了拋出異常的方法改變了程序執行流程,不管這個跳轉使程序掛起還是繼續執行,解釋器都會將其忽略。例如,如果fina1ly從句拋出一個異常,這個異常將替代正在拋出的異常。如果finally從句運行到了return語句,儘管已經拋出了異常且這個拋出的異常還沒有處理,這個方法依然會正常返回。
  在沒有catch從句的情況下try從句可以和finally從句一起使用。在這種情況下,finally塊只包含清理代碼,不管try塊中是否有break、continue或return語句,這裏的代碼一定會執行,回想一下,我們無法完全精確地使用while循環來模擬for循環,因爲continue語句在兩個循環中的行爲表現不一致。如果使用try/finally語句,就能使用while循環來正確模擬包含continue的for循環:

while(test){
    try {body;}
    finally{increment;}
}

  然而需要注意的是,當body包含break語句時,while循環和for循環便有了更微妙的區別,(造成了一次額外的自增運算),因此即便使用了finally從句,使用while來完全模擬for循環依然是不可能的。

其他語句類型(瞭解)

with語句

  作用域鏈(scope chain)是一個可以按序檢索的對象列表,通過它可以進行變量名解析。with語句用於臨時擴展作用域鏈,它具有如下的語法:

with(object)
statement

  這條語句將object添加到作用域鏈的頭部,然後執行statement,最後把作用域鏈恢復到原始狀態。
  在
嚴格模式中是禁止使用with語句的,並且在非嚴格模式裏也是不推薦使用with語句的,儘可能避免使用with語句。那些使用with語句的JavaScript代碼非常難於優化,並且同沒有使用with語句的代碼相比,它運行得更慢。
  在對象嵌套層次很深的時候通常會使用with語句來簡化代碼編寫。例如,在客戶端JavaScript中,可能會使用類似下面這種表達式來訪問一個HTML表單中的元素:

document.forms[o].address.value

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

with(document.forms[o]){
    //直接訪問表單元素,例如:
    name.value="";
    address.value="";
    email.value="";
}

  這種方法減少了大量的輸入,不用再爲每個屬性名添加document.forms[o]前綴。這個對象臨時掛載在作用域鏈上,當JavaScript需要解析諸如address的標識符時,就會自動在這個對象中查找。當然,不使用with語句的等價代碼可以寫成這樣:

var f=document.forms[o];
f.name.value="";
f.address.value="";
f.email.value="";

  只有在查找標識符的時候纔會用到作用域鏈,創建新的變量的時候不使用它,看一下下面這行代碼:

with(o)x=1;

  如果對象o有一個屬性x,那麼這行代碼給這個屬性賦值爲1。但如果o中沒有定義屬性x,這段代碼和不使用with語句的代碼x=1是一模一樣的。它給一個局部變量或者全局變量x賦值,或者創建全局對象的一個新屬性。with語句提供了一種讀取。的屬性的快捷方式,但它並不能創建o的屬性。

debugger語句

  debugger語句通常什麼也不做。然而,當調試程序可用並運行的時候,JavaScript解釋器將會(非必需)以調式模式運行。實際上,這條語句用來產生一個斷點(breakpoint),JavaScript代碼的執行會停止在斷點的位置,這時可以使用調試器輸出變量的值、檢查調用棧等。

"use strict"

  “use strict”是ECMAScript5引入的一條指令。指令不是語句(但非常接近於語句)。“use strict”指令和普通的語句之間有兩個重要的區別:

  • 它不包含任何語言的關鍵字,指令僅僅是一個包含一個特殊字符串直接量的表達式(可以是使用單引號也可以使用雙引號),對於那些沒有實現ECMAScript5的JavaScript解釋器來說,它只是一條沒有副作用的表達式語句,它什麼也沒做。將來的ECMAScript標準希望將use用做關鍵字,這樣就可以省略引號了。
  • 它只能出現在腳本代碼的開始或者函數體的開始、任何實體語句之前。但它不必一定出現在腳本的首行或函數體內的首行,因爲“use strict”指令之後或之前都可能有其他字符串直接量表達式語句,並且JavaScript的具體實現可能將它們解析爲解釋器自有的指令。在腳本或者函數體內第一條常規語句之後字符串直接量表達式語句只當做普通的表達式語句對待;它們不會當做指令解析,它們也沒有任何副作用。

嚴格模式(瞭解)

  • 在嚴格模式中禁止使用with語句。
  • 在嚴格模式中,所有的變量都要先聲明,如果給一個未聲明的變量、函數、函數參數、catch從句參數或全局對象的屬性賦值,將會拋出一個引用錯誤異常(在非嚴格模式中,這種隱式聲明的全局變量的方法是給全局對象新添加一個新屬性)。
  • 在嚴格模式中,調用的函數(不是方法)中的一個this值是undefined。(在非嚴格模式中,調用的函數中的this值總是全局對象)。可以利用這種特性來判斷JavaScript實現是否支持嚴格模式:
var hasstrictMode=(function(){"use strict";return this===undefined}());
  • 同樣,在嚴格模式中,當通過ca11()或apply()來調用函數時,其中的this值就是通過ca11()或apply()傳入的第一個參數(在非嚴格模式中,nu11和undefined值被全局對象和轉換爲對象的非對象值所代替)。
  • 在嚴格模式中,給只讀屬性賦值和給不可擴展的對象創建新成員都將拋出一個類型錯誤異常(在非嚴格模式中,這些操作只是簡單地操作失敗,不會報錯)。
  • 在嚴格模式中,傳入eva1()的代碼不能在調用程序所在的上下文中聲明變量或定義函數,而在非嚴格模式中是可以這樣做的。相反,變量和函數的定義是在eval()創建的新作用域中,這個作用域在eval()返回時就棄用了。
  • 在嚴格模式中,函數裏的arguments對(見8.3.2節)擁有傳入函數值的靜態副本。在非嚴格模式中,arguments對象具有“魔術般”的行爲,arguments裏的數組元素和函數參數都是指向同一個值的引用。
  • 在嚴格模式中,當delete運算符後跟隨非法的標識符(比如變量、函數、函數參數)時,將會拋出一個語法錯誤異常(在非嚴格模式中,這種delete表達式什麼也沒做,並返回false)。
  • 在嚴格模式中,試圖刪除一個不可配置的屬性將拋出一個類型錯誤異常(在非嚴格模式中,delete表達式操作失敗,並返回false)。
  • 在嚴格模式中,在一個對象直接量中定義兩個或多個同名屬性將產生一個語法錯誤(在非嚴格模式中不會報錯)。
  • 在嚴格模式中,函數聲明中存在兩個或多個同名的參數將產生一個語法錯誤(在非嚴格模式中不會報錯)。
  • 在嚴格模式中是不允許使用八進制整數直接量(以0爲前綴,而不是0x爲前綴)的(在非嚴格模式中某些實現是允許八進制整數直接量的)。
  • 在嚴格模式中,標識符eval和arguments當做關鍵字,它們的值是不能更改的。不能給這些標識符賦值,也不能把它們聲明爲變量、用做函數名、用做函數參數或用做catch塊的標識符。
  • 在嚴格模式中限制了對調用棧的檢測能力,在嚴格模式的函數中,arguments.caller和arguments.callee都會拋出一個類型錯誤異常。嚴格模式的函數同樣具有caller和arguments屬性,當訪問這兩個屬性時將拋出類型錯誤異常(有一些JavaScript的實現在非嚴格模式裏定義了這些非標準的屬性)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章