2011-12-28 142 views
121

我一直在瀏覽Mozilla開發者網絡上的JavaScript參考,並且遇到了一個叫做"strict mode"的東西。我把它讀完了,我很難理解它的功能。有人可以簡單地解釋(一般)它的目的是什麼以及它的用途如何?什麼是「嚴格模式」,它是如何使用的?

+1

相關:http://stackoverflow.com/q/1335851/1461424 – Krumia 2016-08-05 04:04:09

回答

135

其主要目的是做更多的檢查。

只需在代碼頂部添加"use strict";即可。

例如,blah = 33;是有效的JavaScript。這意味着你創建了一個完全全局變量blah

但是在嚴格模式下它的錯誤是因爲您沒有使用關鍵字「var」來聲明變量。

大部分時間你不是說在一些任意範圍的中間創建全局變量,所以大部分是blah = 33寫它的時候是一個錯誤,程序員實際上並沒有想讓它是一個全局變量,他們的意思是寫var blah = 33

它同樣不允許很多技術上有效的事情。 NaN = "lol"不會產生錯誤。它也不會改變NaN的值。嚴格使用(和類似的怪異聲明)會產生錯誤。大多數人都讚賞這一點,因爲沒有理由永遠不會寫NaN = "lol",所以最有可能是一個錯字。加入

Read more at the MDN page on strict mode

+4

這是在在MDN – nkcmr 2011-12-28 03:13:15

+23

你不明白什麼它的效用則文件完全相同的副本?它旨在通過捕捉有效但最可能錯誤的事物來幫助開發。 – 2011-12-28 03:19:05

20

嚴格的模式,這樣會有的EcmaScript的易靜態分析的子集,這將是在未來的版本中一個很好的目標。嚴格模式的設計也是希望限制嚴格模式的開發人員能夠減少錯誤,並且他們所做的錯誤會以更明顯的方式體現出來。

Harmony,這將有望成爲下一個主要版本的EcmaScript將建立在ES5嚴格的基礎之上。

Harmony建立在ES5嚴格模式上以避免太多模式。

其他一些語言實驗也依賴於嚴格模式。 SES取決於ES5嚴格模式的可分析性。

SES(安全的ECMAScript)設計實驗

設計通過消除或ES5 /嚴格的修復功能對象能力的編程語言。

應該有一個從SES到ES5/Strict的直接翻譯。

Annex C該標準解釋了嚴格模式和正常模式之間的區別。

嚴格的模式限制和例外

  • 標識符 「工具」, 「接口」, 「讓」, 「包」, 「私人」, 「保護」, 「公」,「靜「和」收益率「在嚴格模式代碼中被歸類爲FutureReservedWord令牌。 (7.6.12 [?])。
  • 符合實現,當處理嚴格模式代碼時,不能擴展NumericLiteral(7.8.3)的語法,使其包含如B.1.1所述的OctalIntegerLiteral。
  • 當處理嚴格模式代碼(見10.1.1)時,一致性實現可能不會擴展EscapeSequence的語法以包含如B.1.2中所述的OctalEscapeSequence。
  • 分配給未聲明的標識符或其他無法解析的引用不會在全局對象中創建屬性。在嚴格模式代碼中發生簡單分配時,其LeftHandSide不能評估爲無法解析的引用。如果它引發ReferenceError異常(8.7.2)。 LeftHandSide也可能不是具有屬性值{[[Writable]]:false}的數據屬性對具有屬性值{[[Set]:undefined}的訪問器屬性的引用,也不是對不存在的屬性值的引用其[[Extensible]]內部屬性值爲false的對象的屬性。在這些情況下會引發TypeError異常(11.13.1)。
  • 標識符eval或參數可能不會顯示爲賦值運算符(11.13)或PostfixExpression(11.3)的LeftHandSideExpression,也可能不是由前綴增量(11.4.4)或前綴遞減(11.4)操作的UnaryExpression。 5)運營商。 嚴格模式函數的參數對象定義了名爲「caller」和「callee」的非可配置訪問器屬性,它在訪問時引發TypeError異常(10.6)。
  • 嚴格模式函數的參數對象不會動態共享其數組索引屬性值與其函數的相應形式參數綁定。 (10.6)。 對於嚴格模式函數,如果創建參數對象,則局部標識符參數與參數對象的綁定是不可變的,因此可能不是賦值表達式的目標。 (10.5)。
  • 如果嚴格模式代碼包含具有任何數據屬性(11.1.5)的多個定義的ObjectLiteral,則它是SyntaxError。 如果標識符「eval」或標識符「參數」作爲嚴格代碼中包含的PropertyAssignment的PropertySetParameterList中的標識符出現,或者其FunctionBody是嚴格代碼(11.1.5),則它是SyntaxError。
  • 嚴格模式eval代碼無法在調用方的變量環境中實例化變量或函數以評估。相反,會創建一個新的變量環境,並將該環境用於eval代碼(10.4.2)的聲明綁定實例化。
  • 如果在嚴格模式代碼中對此進行評估,則該值不會強制轉換爲對象。 null或undefined的這個值不會轉換爲全局對象,並且原始值不會轉換爲包裝器對象。通過函數調用傳遞的值(包括使用Function.prototype.apply和Function.prototype.call調用的函數)不會強制將此值傳遞給對象(10.4.3,11.1.1,15.3.4.3,15.3。 4.4)。
  • 當嚴格模式代碼中出現刪除操作符時,如果其UnaryExpression是對變量,函數參數或函數名稱(11.4.1)的直接引用,則會拋出SyntaxError。
  • 當在嚴格模式代碼內發生刪除操作時,如果要刪除的屬性具有屬性{[[Configurable]]:false}(11.4.1),則會引發TypeError。 如果VariableDeclaration或VariableDeclarationNoIn發生在嚴格代碼內,並且其標識符是eval或參數(12.2.1),則它是SyntaxError。
  • 嚴格模式代碼可能不包含WithStatement。在這種情況下發生WithStatement是一個SyntaxError(12.10)。
  • 它是一個SyntaxError如果與釣TryStatement內嚴格代碼發生和捕撈產量的標識符是EVAL或參數(12.14.1)
  • 它是一個SyntaxError如果標識符EVAL或參數出現FormalParameterList內嚴格模式函數聲明或函數表達式(13.1)
  • 嚴格模式函數可能沒有兩個或更多具有相同名稱的形式參數。使用FunctionDeclaration,FunctionExpression或Function構造函數創建此類函數的嘗試是SyntaxError(13.1,15.3.2)。
  • 除了本規範中定義的實現外,實現不能擴展名爲調用者或函數實例參數的屬性的嚴格模式函數中的含義。 ECMAScript代碼可能不會在與嚴格模式函數(10.6,13.2,15.3.4.5.3)對應的函數對象上創建或修改具有這些名稱的屬性。
  • 這是一個SyntaxError,它在嚴格模式中使用標識符eval或參數作爲FunctionDeclaration或FunctionExpression的標識符或作爲形式參數名稱(13.1)。嘗試使用Function構造函數(15.3.2)動態定義這樣的嚴格模式函數將引發SyntaxError異常。在西蒙的回答不是已經提到的嚴格模式
28

一個方面是嚴格模式將通過函數調用調用的函數thisundefined

這樣

function Obj() { 
    this.a = 12; 
    this.b = "a"; 
    this.privilegedMethod = function() { 
     this.a++; 
     privateMethod(); 
    }; 

    function privateMethod() { 
    this.b = "foo"; 
    } 
} 

那麼事情會導致當privateMethod被稱爲(因爲你不能將屬性添加到undefined)的錯誤,而不是無謂地增加了b屬性的全局對象。

+4

是的,需要添加'privateMethod.bind(this)();'並用'new' ['jsbin.com'](https://jsbin.com/foyomo/edit?html,js,console) – hlcs 2016-05-15 05:01:51

5

嚴格模式對正常的JavaScript語義進行了一些更改。

  • 嚴格模式通過更改錯誤來消除一些JavaScript靜默錯誤。

  • 嚴格模式修復了JavaScript引擎難以執行優化的錯誤。

  • 嚴格模式禁止在將來版本的ECMAScript中定義一些可能的語法。

1

ECMAScript5引入了一些新的對象和屬性,也即所謂的"strict mode"

嚴格模式是排除不推薦使用的功能的語言的子集。嚴格的 模式是選擇加入而不是必需的,這意味着如果您希望您的代碼在嚴格模式下運行,您可以使用(每個函數一次,或整個程序的一次)聲明您的意圖以下字符串:

"use strict"; 
6

的ECMAScript 5中引入的嚴格模式概念。

調用嚴格模式的代碼

嚴格模式適用於整個腳本或個別功能。它不適用於包含在{}括號中的塊語句,試圖將其應用於這樣的上下文什麼都不做。

整個腳本:

讓我們說,我們正在創建app.js因此增加第一條語句使用腳本將執行嚴格的模式全部代碼。

// app.js whole script in strict mode syntax 
「use strict」; 
// Now you can start writing your code 

的功能嚴格模式:

援引嚴格模式的功能,把確切的聲明「使用嚴格的」;在任何其他語句之前的函數體的開始。

function yourFunc(){ 
"use strict"; 

// Your function code logic 
} 

嚴格模式包含對正常的Javascript語義的幾個變化。第一嚴格模式通過更改錯誤來消除JavaScript靜默錯誤。

如:使用代碼嚴格模式

enter image description here

在上面的代碼示例而不代碼使用嚴格模式它不會引發錯誤。因爲我們正在訪問變量x而沒有聲明它。所以在嚴格模式下訪問未聲明的變量會拋出一個錯誤。

現在讓我們嘗試訪問變量x,而不是在沒有嚴格模式的情況下聲明它。

(function(){ 
    x = 3; 
})(); 

// Will not throw an error 

使用嚴格模式的優勢:

  • 消除的JavaScript拋出錯誤無記載錯誤。
  • 修復了使JavaScript引擎難以執行優化的錯誤。
  • 使代碼的運行速度比非嚴格模式下的相同代碼快
  • 禁止在未來版本的ECMAScript中定義某些語法。
0

2017年,我終於找到了文檔:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

嚴格模式是可以選擇適用的JavaScript的限制變種的一種方式。 嚴格模式不僅僅是一個子集:它有意與正常代碼有不同的 語義。不支持嚴格模式的瀏覽器 運行嚴格模式代碼,其瀏覽器的行爲不同,因此 不依賴於嚴格模式,沒有功能測試以支持嚴格模式的 相關方面。嚴格模式代碼和非嚴格模式 代碼可以共存,因此腳本可以漸進地選擇嚴格模式。


嚴格模式提出了一些修改普通的JavaScript語義。 首先,嚴格模式通過將 更改爲拋出錯誤來消除一些JavaScript靜默錯誤。其次,嚴格模式修復了以下錯誤: 使JavaScript引擎難以執行優化: 嚴格模式代碼有時可能會運行得比相同的 代碼不是嚴格模式。第三,嚴格模式禁止在將來版本的ECMAScript中定義一些語法 。

相關問題