嚴格模式來鎮

2010年12月14日,2:12 PM由Douglas Crockford | 開發 | 20評論

這是時間和季節,當世界各地的人們忘記了他們之間的分歧,並在和平和友誼,共同慶祝一週年ECMA大會批准的ECMAScript的編程語言標準,第五版。 ES5中最重要的特點是嚴格的新模式。 嚴格模式是一種選擇的模式,修理或消除語言的最棘手的一些特點。

指定嚴格模式

有兩種方式,要求嚴格模式。 首先是插入該pragma

  “使用嚴格”; 

在一個文件或編譯單元的頂部。 它必須出現在任何其他的語句,但它可能是由前面的空白和註釋。 它有一個無用的字符串文字敘述的形式,使ES3的系統,它將被忽略。 這意味著,它有可能,寫ES5/strict方案,也可以運行在舊的瀏覽器。 嚴格的代碼也可以交互與非嚴格的代碼(或馬虎 ),所以嚴格的函數可以調用馬虎的功能,草率的函數可以調用嚴格的功能。 這種高度的兼容性,通過嚴格的模式容易。

嚴格的代碼將處理所有代碼中的文件或編譯單元"use strict";序言。 有一個問題,雖然性能方面的考慮,目前迫使我們一起串連許多JavaScript文件,以避免累積的HTTP延遲。 如果一個文件"use strict";的序言有馬虎的代碼追加到它,草率的代碼將作為嚴格的處理,可能會失敗。 有一個簡單的規則:不要在嚴格相同的文件和草率,但我們已經看到一些著名的網站得到這個錯誤。

第二種方式是作為一個函數的第一條語句插入的pragma。 聲明的整體功能,將是嚴格的,包括任何嵌套在它的功能。 寬嚴方面的功能範圍,如此嚴格的代碼和草率的代碼可以混合在同一個文件。 這第二種形式與模塊模式和它的許多變化,工作得非常好。 第二種形式是首選,因為它避免了串聯危險。

  (函數(){
    “使用嚴格”;
    / /這個函數是嚴格...
 }());

 (函數(){
    / /但是這個功能是馬虎...
 }()); 

範圍

從歷史上看,JavaScript已經困惑如何職能範圍。 有時候,他們似乎是靜態範圍,但某些功能,使他們像他們動態範圍。 這是混亂的,使程序難以閱讀和理解。 誤解造成的錯誤。 它也是一個性能問題。 靜態作用域將允許綁定變量在編譯時發生,但動態範圍的要求意味著必須綁定推遲到運行時,其中一個顯著的性能損失。

嚴格模式要求所有的變量綁定靜態進行。 這意味著,以前需要動態綁定的功能,必須消除或修改。 具體來說, 與語句被淘汰, eval函數的能力,篡改它的調用者的環境受到嚴重限制。

嚴格的代碼的好處之一是,像工具YUI壓縮可以做得更好處理。

隱含的全局變量

JavaScript已暗示了全局變量。 如果你不顯式聲明一個變量,全局變量是隱式聲明為你。 這使得編程的初學者更容易,因為他們可以忽略其基本的家務瑣事。 但它使較大的程序的管理困難得多,它大大降低可靠性。 因此,在嚴格模式下,隱含全局變量不再創建。 你應該明確聲明所有的變量。

全球洩漏

有很多的情況下,可能會導致this勢必全局對象。 例如,如果你忘記調用構造函數時提供了new前綴this將勢必意外的全局對象構造函數的,而不是初始化一個新的對象,因此,它反而會默默地與全局變量篡改。 在這種情況下,嚴格的模式,而不是將this undefined ,這將導致構造函數拋出異常,而是允許更快被檢測到的錯誤。

嘈雜的失敗

JavaScript已只讀屬性,但你不能創建它們自己,直到ES5的Object.createProperty功能暴露了這種能力。 如果試圖分配一個值到一個只讀屬性,它會靜靜的失敗。 轉讓不會改變財產的價值,但你的程序將繼續進行,儘管它有。 這是一個完整的危險,可能會導致程序進入不一致的狀態。 在嚴格模式下,試圖改變一個只讀的屬性,將拋出一個異常。

八路

八進制(基數為8)的數字代表的是做機器級編程的機器上的字的大小分別為3的倍數時非常有用。 你需要八進制時,工作與疾病預防控制中心6600大型機,其中有一個60位的字的大小。 如果你能讀八進制,你可以看作為20位的字。 兩位數字表示運算的代碼,和一個數字確定的8個寄存器之一。 在緩慢的過渡,從機器代碼高級語言,它被認為是有用的編程語言中的八進制形式提供。

在C中,一個極為不幸的代表性octalness選擇:前導零。 因此,在C,0100意味著64,而不是100,和08是一個錯誤,而不是8。 更不幸的是,這種不合時宜的已被複製到幾乎所有的現代語言,包括JavaScript,它僅用於創建錯誤。 它有沒有其他目的。 因此,在嚴格模式下,不再允許八進制形式。

等等

arguments偽陣列成為多一點點在ES5類似數組。 在嚴格模式下,它失去了它的calleecaller屬性。 這使得它可以通過你的arguments而放棄了很多保密的情況下不受信任的代碼。 此外, arguments功能的財產被淘汰。

在嚴格模式下,重複鍵功能常會產生一個語法錯誤。 具有相同名稱的函數不能有兩個參數。 函數不能有一個變量具有相同的名稱作為它的參數之一。 函數不能delete自己的變量。 試圖delete一個非配置屬性現在拋出一個異常。 原始值不隱裹。

如果你的程序通過JSLint ,它可能會在嚴格模式下工作。

它仍然是一個不完美的世界

在JavaScript中仍然存在的問題,嚴格模式沒有解決。 例如,插入分號仍然是危險,和0.1 + 0.2仍是不等於0.3。 糾正這些問題,將不得不等待未來版本。

為什麼要嚴格模式事宜

在嚴格模式除了程序的可靠性和可讀性明顯的好處,幫助解決混搭問題。 我們希望能夠邀請到我們的網頁第三方的代碼,做有用的東西,沒有給這些代碼的許可證接管瀏覽器或歪曲自己的用戶或我們的服務器,為我們和我們的用戶。 我們需要約束的第三方代碼。 像系統谷歌的卡哈做到這一點,但在顯著的成本,在性能和不便。 自己ADsafe系統也這樣做,但在消除成本this []標從語言,它可以使通過困難。 嚴格模式,使我們能夠第三方代碼的方便性和性能的ADsafe卡哈表現。 我們的網站變得更加複雜和更加緊密,這將是極為重要的。

嚴格的模式不解決XSS問題。 這個問題的解決取決於採取了一些積極的行動W3C的

ES5/strict現在是預覽,並很快將在所有符合標準的瀏覽器中無處不在的標準設備。

共享和擴展: 書籤del.icio.us Digg它! | reddit!

20評論

  1. 像往常一樣真棒職位! ES5是未來...... Object.create()中,Object.defineProperty()中,Object.isExtensible(),Array.isArray(),原生支持JSON的強大功能......檢查ADsafe,前景看好

    評論由塞巴斯Armeli - 12月14日,2010

  2. 如果arguments.callee是,有拉姆達引用從它身上的另一種方式?

    評論亞利耶 - 12月15日,2010

  3. 是否有任何瀏覽器(測試版)是完全嚴格的模式符合嗎?

    內特- 12月15日,2010

  4. @亞利耶,沒錯 -

    var carl = function bob(a) {
    if (!a) { bob(1); } // reference scoped to inside this function
    alert(carl === bob); // gotcha - true in all browsers but false in ie...
    };

    克里斯 - 12月15日,2010

  5. 亞利耶:您可以命名函數表達式和參考,他們的名字。 var x = function lookMaNoYCombinator(a, b) { if (a === 0) return a + b; else return lookMaNoYCombinator(a - 1, b) }

    評論由薩米Samhuri - 12月15日,2010

  6. @亞利耶:你應該使用一個命名的lambda,如果你想遞歸。 例如。 (函數f(){F()})。 這也有優勢不綁定的論據反對|這|

    奧利弗 - 12月15日,2010

  7. @內特:每晚構建的WebKit和Firefox都應該嚴格的模式符合,我們都明白被提交的缺陷,如果你發現任何(在http://bugs.webkit.orghttp://bugs.mozilla.org)

    奧利弗 - 12月15日,2010

  8. 一個偉大的圖表顯示,在各種瀏覽器兼容性ES5可以在這裡找到: http://kangax.github.com/es5-compat-table/

    吉米 - 12月15日,2010

  9. '與'和注射EVAL 沒有真正實現動態綁定 甚至完全ES3的使用在所有情況下的詞法綁定(雖然不一定是靜態綁定)。 當然這些功能混亂,雖然。

    評論由大衛·薩拉霍普伍德- 12月16日,2010

  10. 您好道格拉斯,

    很好的概述,謝謝。 此外,我相信你的讀者將在詳細嚴格的模式說明感興趣: http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/

    PS:一雙補充/更正:

    函數不能有一個變量具有相同的名稱作為它的參數之一。

    這是確定有一個相同的名稱作為參數之一的變量聲明。 技術上,聲明將只跳過,因為它已經宣布通過參數綁定。

    函數不能刪除自己的變量。

    它總是讓-變量(除了那些使用eval上下文創建)總是有ES3的/ {DontDelete} [配置]] =在ES5假。 即它不可能刪除一個變量,無論在嚴格模式。

    德米特里。

    評論梅德A. Soshnikov - 12月17日,2010

  11. YUI3將添加“使用嚴格”,它的模塊?

    大衛- 12月17日,2010

  12. 您好道格拉斯

    在下面的語句從你的文章我很困惑。

    “嚴格模式要求所有的變量綁定靜態進行。 這意味著,以前需要動態綁定的功能,必須消除或修改“

    關鍵字“” - 它是否有動態綁定或詞彙(靜態)綁定?

    如果它有動態綁定,你的意思是說我們應該停止使用嚴格模式'這個'?

    我真的很困惑。 我開始學習JavaScript的最後1個月,從您的視頻演示。 他們是非常有幫助。 這是我的第一編程語言。 可能是我的疑問是很奇怪。

    只是想從你聽到“這”無疑。

    謝謝

    評論ekanna - 12月28日,2010

  13. 在嚴格模式下,該方法的形式綁定對象之前。 函數的形式,結合本不確定的,而不是全局對象。

    Douglas Crockford - 12月29日,2010

  14. 德米特里,你剛才所描述的情況下,可以使變量,然後可以刪除! delete運算符的語法允許這種情況下,變量完全相同。 但沒有更多。

    和大衛 - 薩拉,你是分裂的頭髮很短。

    Douglas Crockford - 12月29日,2010

  15. 感謝道格拉斯。

    評論ekanna - 2011年1月7日

  16. 可能要糾正“喧鬧失敗”錯字節“createProperty”應該是“defineProperty”的。

    特拉維斯- 2011年1月11日,

  17. “嚴格真棒”

    評論由弗朗茨enzenhofer - 2011年1月13日,

  18. 克羅克福德rockz!

    評論由Marc德拉科- 2011年1月20日

  19. 所以,當YUI的壓縮機將停止下降“使用嚴格的”代碼雜在minifaction? :)

    評論marcoos - 2月3日,2011年

  20. S / minifaction /微小/

    評論marcoos - 2月3日,2011年

很抱歉,評論已被封閉,在這個時候。

主辦雅虎

©2006-2012雅虎公司所有權利保留。 隱私政策 - 服務條款

支持WordPress的關於雅虎 虛擬主機