18519
19090
最近,我通過Crockford的JSLint運行了一些JavaScript代碼,並給出了以下錯誤:
第1行第1個字符處的問題:缺少“使用嚴格”語句。
進行搜索後,我發現有些人添加了“ use strict”;納入他們的JavaScript代碼。添加語句後,錯誤停止出現。不幸的是,谷歌沒有透露此字符串語句背後的許多歷史。當然,它一定與瀏覽器如何解釋JavaScript有關,但是我不知道會有什麼影響。
那麼什麼是“嚴格使用”?所有這些,這意味著什麼,並且它仍然有意義嗎?
當前的瀏覽器是否響應“嚴格使用”;字符串還是將來使用? 
這篇有關Javascript嚴格模式的文章可能會讓您感興趣:John Resig-ECMAScript 5嚴格模式,JSON等
引用一些有趣的部分:
嚴格模式是ECMAScript 5中的一項新功能,可讓您將程序或功能置於“嚴格”的操作環境中。這種嚴格的上下文會阻止採取某些措施,並引發更多異常。
和:
嚴格模式可以通過以下兩種方式提供幫助:
它捕獲了一些常見的編碼漏洞,並引發異常。
當採取相對“不安全”的操作(例如獲得對全局對象的訪問權限)時,它可以防止或引發錯誤。
它禁用令人困惑或考慮不周的功能。
還要注意,您可以將“嚴格模式”應用於整個文件...或者您可以將其僅用於特定功能(仍引用John Resig的文章):
//非嚴格代碼...
(功能(){
“使用嚴格”;
//嚴格定義您的庫...
})();
//非嚴格代碼...
如果您必須混合使用舊代碼和新代碼,這可能會有所幫助;-)
因此,我想這有點像您可以在Perl中使用“嚴格使用”(因此得名?):它通過檢測更多可能導致損壞的內容來幫助您減少錯誤。
所有主要瀏覽器現在都支持嚴格模式。
在本機ECMAScript模塊(帶有導入和導出語句)和ES6類中,嚴格模式始終處於啟用狀態,不能被禁用。
|
這是ECMAScript 5的新功能。JohnResig對此進行了很好的總結。
它只是您放入JavaScript文件(位於文件頂部或位於函數內部)的字符串,如下所示:
“使用嚴格”;
現在將其放入您的代碼中應該不會對當前的瀏覽器造成任何問題,因為它只是一個字符串。如果您的代碼違反了編譯指示,將來可能會導致您的代碼出現問題。例如,如果您當前具有foo =“ bar”而不首先定義foo,則您的代碼將開始失敗...在我看來,這是一件好事。
|
聲明“使用嚴格”;指示瀏覽器使用嚴格模式,這是JavaScript的簡化和安全功能集。
功能列表(非窮舉)
禁止使用全局變量。 (捕獲變量名稱中缺少的var聲明和錯別字)
靜默失敗的分配將在嚴格模式下引發錯誤(分配NaN = 5;)
嘗試刪除不可刪除的屬性將引發(刪除Object.prototype)
要求對象文字中的所有屬性名稱必須唯一(var x = {x1:“ 1”,x1:“ 2”})
函數參數名稱必須唯一(函數總和(x,x){...})
禁止使用八進制語法(var x = 023;某些開發人員錯誤地認為前面的零不會更改數字。)
禁止with關鍵字
嚴格模式下的eval不會引入新變量
禁止刪除純名稱(刪除x;)
禁止以任何形式綁定或分配名稱eval和參數
嚴格模式不會將參數對象的屬性與形式參數混用。 (即函數sum(a,b){return arguments [0] + b;}之所以有效,是因為arguments [0]綁定到a上,依此類推。)
不支持arguments.callee
[參考:嚴格模式,Mozilla開發人員網絡]
|
如果人們擔心使用嚴格的使用,那麼可能值得閱讀這篇文章:
瀏覽器中的ECMAScript 5“嚴格模式”支持。這是什麼意思?NovoGeek.com-克里希納的博客
它討論了瀏覽器支持,但更重要的是如何安全地處理它:
函數isStrictMode(){
返回!
}
/ *
返回false,因為'this'指向全局對象,並且
'!這'變成假
* /
函數isStrictMode(){
“使用嚴格”;
返回!
}
/ *
返回true,因為在嚴格模式下,關鍵字“ this”
與傳統的JS不同,它不引用全局對象。
所以在這裡,“ this”是“ undefined”,“!this”變為true。
* /
|
提醒您,所有苛刻的程序員:對現有代碼應用“嚴格使用”可能很危險!這東西不是一些讓人感覺愉悅,表情愉悅的標籤,您可以在代碼上打一下以使其“更好”。使用“嚴格使用”雜語,瀏覽器會突然在從未發生過的隨機位置拋出異常,這僅僅是因為您正在執行默認/寬鬆JavaScript允許但嚴格JavaScript討厭的事情!您可能會遇到嚴格的違規情況,這些隱瞞了您的代碼中很少使用的調用,這些調用只會在最終運行時才會引發異常-例如,在付費客戶使用的生產環境中!
如果您要嘗試一下,最好將“使用嚴格”與全面的單元測試以及嚴格配置的JSHint構建任務一起應用,這將使您充滿信心,您的模塊不會出現死角可怕的是,因為您已啟用嚴格模式。或者,嘿,這是另一種選擇:只是不要在您的任何舊代碼中添加“ use strict”,說實話這可能更安全。絕對不要在您不擁有或沒有的任何模塊中添加“使用嚴格”像第三方模塊一樣進行維護。
我認為,即使這是一種致命的籠養動物,“嚴格使用”也可能是好東西,但您必須正確地做。嚴格執行的最佳時間是當您的項目處於未開發狀態並且從頭開始時。在JSHint / JSLint上配置所有警告和選項,使您的團隊可以緊緊抓住,並在諸如Grunt + Karma + Chai之類的操縱條件下獲得良好的構建/測試/聲明系統,然後只有THEN才開始將所有新模塊標記為“使用嚴格”。準備好解決許多小錯誤和警告。如果JSHint / JSLint產生任何違規,請通過將構建配置為FAIL來確保每個人都了解重力。
當我採用“使用嚴格”時,我的項目不是一個新項目。結果,我的IDE充滿了紅色標記,因為我對模塊的一半沒有“嚴格使用”,而JSHint對此表示抱怨。這讓我想起了將來應該做的重構。我的目標是由於我遺漏了所有“嚴格使用”聲明,因此沒有紅標,但是距離現在還很遠。
|
使用“嚴格使用”;不會突然使您的代碼變得更好。
JavaScript嚴格模式是ECMAScript 5中的一項功能。您可以通過在腳本/函數頂部進行聲明來啟用嚴格模式。
“嚴格使用”;
當JavaScript引擎看到此指令時,它將開始以特殊模式解釋代碼。在這種模式下,當檢測到某些可能最終成為潛在錯誤的編碼實踐時,就會引發錯誤(這是嚴格模式下的原因)。
考慮以下示例:
var a = 365;
var b = 030;
為了吸引數字文字,開發人員在不經意間將變量b初始化為八進製文字。非嚴格模式會將其解釋為帶有值24(以10為底)的數字文字。但是,嚴格模式將引發錯誤。
有關嚴格模式下的專業的詳盡列表,請參見此答案。
我應該在哪裡使用“嚴格使用”;?
在我的新JavaScript應用程序中:絕對!當您對代碼進行愚蠢的操作時,嚴格模式可以用作舉報人。
在我現有的JavaScript代碼中:可能不是!如果您現有的JavaScript代碼中的語句在嚴格模式下被禁止,則應用程序將很容易崩潰。如果要使用嚴格模式,則應該準備調試和更正現有代碼。這就是為什麼使用“嚴格使用”的原因;不會突然使您的代碼變得更好。
如何使用嚴格模式?
插入“使用嚴格”;腳本頂部的語句:
//文件:myscript.js
“使用嚴格”;
var a = 2;
....
請注意,文件myscript.js中的所有內容都將以嚴格模式進行解釋。
或者,插入“使用嚴格”;在函數體頂部的語句:
函數doSomething(){
“使用嚴格”;
...
}
函數doSomething的詞法範圍內的所有內容都將以嚴格模式進行解釋。詞彙範圍一詞在這裡很重要。例如,如果您的嚴格代碼調用了非嚴格庫的函數,則僅您的代碼以嚴格模式執行,而不是被調用函數。請參閱此答案以獲得更好的解釋。
嚴格模式下禁止哪些事情?
我找到了一篇不錯的文章,描述了嚴格模式下禁止的幾件事(請注意,這不是排他性清單):
範圍
從歷史上看,JavaScript對於功能如何一直感到困惑
範圍。有時它們似乎是靜態作用域,但有些
功能使它們的行為就像動態範圍一樣。這是
令人困惑,使程序難以閱讀和理解。
誤會導致錯誤。這也是性能問題。
靜態作用域將允許在編譯時進行變量綁定
時間,但是對動態範圍的要求意味著綁定必須是
推遲到運行時,這具有顯著的性能
罰款。
嚴格模式要求所有變量綁定都是靜態完成的。
這意味著以前需要動態綁定的功能
必須刪除或修改。具體來說,with語句是
消除,並且評估功能可以篡改
呼叫者的環境受到嚴格限制。
嚴格代碼的好處之一是像YUI Compressor這樣的工具
在處理它時可以做得更好。
隱含全局變量
JavaScript隱含了全局變量。如果
您沒有顯式聲明變量,而是全局變量
為您隱式聲明。這使得編程更容易
初學者,因為他們可以忽略一些基本的客房清潔服務
瑣事。但這使大型程序的管理更多
困難,並且大大降低了可靠性。所以嚴格
模式下,不再創建隱式全局變量。你應該
顯式聲明所有變量。
全球洩漏
在許多情況下可能會導致這種情況
綁定到全局對象。例如,如果您忘記
在調用構造函數時提供新的前綴功能,
構造函數的this會意外綁定到全局對象,因此
與其初始化一個新對象,不如說它是靜默的
篡改全局變量。在這些情況下,嚴格模式將
而是將其綁定到undefined,這將導致構造函數
而是引發異常,從而使錯誤可以被大量檢測
早點
嘈雜的失敗
JavaScript始終具有隻讀屬性,但是您
在ES5的Object.createProperty之前無法自己創建它們
功能暴露了這種能力。如果您嘗試分配一個值
只讀屬性,它將無提示地失敗。作業將
不會更改屬性的值,但是您的程序將繼續執行
雖然有。這是完整性危害,可能導致程序無法執行
進入不一致狀態。在嚴格模式下,嘗試更改
只讀屬性將引發異常。
八進制
數字的八進制(或基數8)表示形式非常
在其詞的機器上進行機器級編程時很有用
大小是3的倍數。使用CDC時需要八進制
6600大型機,其字長為60位。如果你能讀
八進制,您可以將單詞看成20位數字。代表兩位數
操作碼和一位數字標識8個寄存器之一。在此期間
從機器代碼到高級語言的緩慢轉換
被認為對以編程語言提供八進制形式很有用。
在C語言中,八進制的一種極其不幸的表示是
已選擇:前導零。因此,在C中,0100表示​​64,而不是100,而08是
錯誤,而不是8。更不幸的是,這種不合時宜的原因是
複製到幾乎所有現代語言(包括JavaScript)中,
它僅用於創建錯誤。它沒有其他目的。所以在
嚴格模式下,不再允許使用八進制形式。
等等
參數偽數組變得更多
在ES5中類似於數組。在嚴格模式下,它將丟失被叫方和呼叫方
屬性。這樣就可以將您的論點傳遞給不受信任的對象
無需放棄很多機密上下文的代碼。另外,
函數的arguments屬性被消除。
在嚴格模式下,函數文字中的重複鍵將產生一個
語法錯誤。一個函數不能有兩個具有相同名稱的參數。
函數不能具有與其名稱之一相同的變量
參數。函數不能刪除自己的變量。試圖
刪除一個不可配置的屬性現在會引發異常。原始
值不是隱式包裝的。
將來的JavaScript版本的保留字
ECMAScript 5添加了保留字列表。如果將它們用作變量或參數,則嚴格模式將引發錯誤。保留字為:
實現,接口,讓,打包,私有,受保護,公共,靜態和yield
進一步閱讀
嚴格模式-JavaScript | MDN
瀏覽器對嚴格模式的支持
過渡到嚴格模式
|
我強烈建議每個開發人員立即開始使用嚴格模式。有足夠多的瀏覽器支持它,嚴格模式可以合理地幫助我們避免代碼中甚至不知道的錯誤。
顯然,在初始階段會有一些我們從未遇到過的錯誤。為了獲得全部收益,我們需要在切換到嚴格模式後進行適當的測試,以確保我們已捕獲所有內容。絕對我們不只是在代碼中使用嚴格,並假設沒有錯誤。因此,令人感到奇怪的是,是時候開始使用這一非常有用的語言功能來編寫更好的代碼了。
例如,
var person = {
名稱:'xyz',
位置:“ abc”,
fullname:function(){“使用嚴格”;返回this.name; }
};
JSLint是由Douglas Crockford編寫的調試器。只需粘貼您的腳本,它就會快速掃描代碼中任何明顯的問題和錯誤。
|
我想提供一個更有根據的答案來補充其他答案。我希望編輯最流行的答案,但失敗了。我試圖使它盡可能全面和完整。
您可以參考MDN文檔以獲取更多信息。
“嚴格使用”是ECMAScript 5中引入的指令。
指令與語句相似,但有所不同。
use strict不包含關鍵字:指令是一個簡單的表達式語句,由特殊的字符串文字(單引號或雙引號)組成。沒有實現ECMAScript 5的JavaScript引擎只能看到一個沒有副作用的表達式語句。預計將來的ECMAScript標準版本會引入使用作為真正的關鍵詞;這樣一來,報價就會過時。
use strict只能在腳本或函數的開頭使用,即必須在所有其他(真實)語句之前。它不一定是函數腳本中的第一條指令:它可以在其他由字符串文字(和JavaScript)組成的語句表達式之前實現可以將它們視為實現特定的指令)。緊跟在腳本或函數中的第一個實數語句之後的字符串文字語句是簡單的表達式語句。口譯員不得將其解釋為指令,並且它們無效。
use strict指令指示以下代碼(在腳本或函數中)是嚴格代碼。
當腳本包含使用嚴格指令時,腳本最高級別的代碼(不在函數中的代碼)被視為嚴格代碼。
當函數本身在嚴格代碼中定義或函數包含use strict指令時,該函數的內容被視為嚴格代碼。
當從嚴格代碼調用eval()或包含use strict指令本身時,傳遞給eval()方法的代碼被視為嚴格代碼。
ECMAScript 5的嚴格模式是JavaScript語言的受限子集,它消除了該語言的相關缺陷,並具有更嚴格的錯誤檢查和更高的安全性。下面列出了嚴格模式和普通模式之間的區別(前三個特別重要):
您不能在嚴格模式下使用with語句。
在嚴格模式下,必須聲明所有變量:如果將一個值賦給尚未聲明為全局對象的變量,函數,函數參數,子句參數或屬性的標識符,則將收到ReferenceError。在正常模式下,標識符隱式聲明為全局變量(作為全局對象的屬性)
在嚴格模式下,關鍵字this的值在作為函數(而不是方法)調用的函數中具有未定義的值。 (在正常模式下,它始終指向全局對象)。此差異可用於測試實現是否支持嚴格模式:
var hasStrictMode =(function(){“ use strict”;返回this === undefined}());
同樣,當使用call()調用函數或以嚴格模式應用函數時,這恰好是call()或apply()調用的第一個參數的值。 (在正常模式下,將null和undefined替換為全局Object,並將不是對象的值強制轉換為對象。)
在嚴格模式下,當您嘗試分配給只讀屬性或為不可擴展對象定義新屬性時,將出現TypeError。 (在正常模式下,兩者都只會失敗而不會顯示錯誤消息。)
在嚴格模式下,將代碼傳遞給eval()時,不能在調用方的範圍內聲明或定義變量或函數(就像在常規模式下那樣)。而是為eval()創建一個新範圍,並且變量和函數都在該範圍內。 eval()完成執行後,該作用域被銷毀。
在嚴格模式下,函數的arguments對象包含值的靜態副本,這些值將傳遞給該函數。在正常模式下,arguments-object的行為有些“神奇”:數組的元素和命名的函數參數都引用相同的值。
在嚴格模式下,當delete運算符後跟非限定標識符(變量,函數或函數參數)時,將出現SyntaxError。在正常模式下,delete表達式將不執行任何操作,並被評估為false。
在嚴格模式下,當您嘗試刪除不可配置的屬性時,將出現TypeError。 (在正常模式下,嘗試僅會失敗,並且delete表達式的計算結果為false)。
在嚴格模式下,當您嘗試為對象文字定義名稱相同的多個屬性時,將其視為語法錯誤。 (在正常模式下沒有錯誤。)
在嚴格模式下,當函數聲明具有多個具有相同名稱的參數時,將其視為語法錯誤。 (在正常模式下沒有錯誤。)
在嚴格模式下,不允許使用八進製文字(這些文字以0x開頭。(在正常模式下,某些實現確實允許使用八進製文字。)
在嚴格模式下,標識符eval和參數被視為關鍵字。您不能更改它們的值,不能給它們分配值,也不能將它們用作變量,函數,函數參數或catch塊標識符的名稱。
在嚴格模式下,對檢查調用堆棧的可能性有更多限制。 arguments.caller和arguments.callee在嚴格模式下的函數中導致TypeError。此外,在嚴格模式下,函數的某些調用方和參數屬性會在您嘗試讀取它們時導致TypeError。
|
我的兩分錢:
嚴格模式的目標之一是允許更快地調試問題。當發生某些錯誤事件時,它會引發異常,從而導致您的網頁無聲或奇怪的行為,它可以幫助開發人員。一旦使用嚴格,代碼就會拋出錯誤,這有助於開發人員提前修復它。
在使用strict之後,我學到的一些重要的東西很少:
防止全局變量聲明:
var tree1Data= {名稱:“香蕉樹”,年齡:100,葉數:100000};
函數Tree(typeOfTree){
var age;
var leafCount;
年齡= typeOfTree.age;
leafCount = typeOfTree.leafCount;
nameoftree = typeOfTree.name;
};
var tree1 = new Tree(tree1Data);
console.log(window);
現在,此代碼在全局範圍內創建nameoftree,可以使用window.nameoftree進行訪問。當我們執行嚴格使用時,代碼將引發錯誤。
未捕獲ReferenceError:未定義nameoftree
樣品
用語句消除:
使用uglify-js之類的工具無法縮小with語句。它們也已棄用,並從將來的JavaScript版本中刪除。
樣品
防止重複:
當我們有重複的屬性時,它將引發異常
未捕獲的SyntaxError:對象文字中的重複數據屬性不正確
在嚴格模式下允許
“使用嚴格”;
var tree1Data = {
名稱:“香蕉樹”
年齡:100歲
leafCount:100000,
名稱:“香蕉樹”
};
很少,但是我需要獲得更多的知識。
|
如果您使用的是去年左右發布的瀏覽器,則該瀏覽器很可能支持JavaScript嚴格模式。只有在ECMAScript 5成為當前標準之前的較舊的瀏覽器才不支持它。
該命令周圍的引號確保該代碼在舊版本的瀏覽器中也仍然可以運行(儘管在嚴格模式下生成語法錯誤的內容通常只會導致腳本在舊版本的瀏覽器中以某種難以檢測的方式發生故障)。
|
當添加“ use strict”;時,以下情況將在腳本執行之前引發SyntaxError:
使用新保留的關鍵字之一(在ECMAScript 6的預設中)為將來的ECMAScript版本舖平道路:實現,接口,讓,打包,私有,受保護,公共,靜態和yield。
塊中聲明功能
if(a :3:15)
在<匿名>:6:5
在這裡,編譯器將引發參考錯誤。在嚴格模式下,編譯器不允許我們在未聲明的情況下使用變量。因此可以防止內存洩漏。另外,我們可以編寫更多優化的代碼。
|
嚴格模式消除了在非嚴格模式下將被忽略的錯誤,從而使javascript“更加安全”。
是否被認為是最佳做法?
是的,在使用javascript納入嚴格模式時,它被視為最佳做法的一部分。這是通過在您的JS文件中添加以下代碼行來完成的。
“使用嚴格”;
在您的代碼中。
對用戶代理意味著什麼?
指示應該以嚴格模式解釋代碼,這會向瀏覽器之類的用戶代理指定用戶應按字面意義對待代碼,並在代碼沒有意義時拋出錯誤。
例如:考慮在您的.js文件中,您具有以下代碼:
方案1:[無限制模式]
var city =“芝加哥”
console.log(city)//打印城市名稱,即芝加哥
方案2:[無限制模式]
city =“芝加哥”
console.log(city)//打印城市名稱,即芝加哥
那麼為什麼在兩種情況下都打印變量名呢?
如果未啟用嚴格模式,則用戶代理通常會對有問題的代碼進行一系列修改,以使其變得有意義。從表面上看,這似乎是一件好事,而且確實,在嚴格模式下工作使人們可以在不弄清所有細節的情況下使用JavaScript代碼。但是,作為開發人員,我不想在我的代碼中留下錯誤,因為我知道它可能會回來並在以後咬住我,我也只想編寫出色的代碼。這就是嚴格模式可以提供幫助的地方。
方案3:[嚴格模式]
“使用嚴格”;
city =“芝加哥”
console.log(city)//參考錯誤:賦值是未聲明的變量city。
附加提示:要使用嚴格模式保持代碼質量,則無需一遍又一遍地編寫代碼,特別是如果您有多個.js文件。您可以在eslint規則中全局實施此規則,如下所示:
文件名:.eslintrc.js
module.exports = {
信封:{
es6:是
},
規則:{
嚴格:['錯誤','全局'],
},
};
好吧,那麼嚴格模式下可以防止什麼呢?
在不聲明變量的情況下使用變量將在嚴格模式下引發錯誤。這是為了防止在整個應用程序中意外創建全局變量。印刷芝加哥的示例特別涵蓋了這一點。
在嚴格模式下,刪除變量,函數或參數是不可以的。
“使用嚴格”;
函數x(p1,p2){};
刪除x; //這會導致錯誤
在嚴格模式下,不允許重複參數名稱。
“使用嚴格”;
函數x(p1,p1){}; //這會導致錯誤
嚴格模式下不允許使用Java語言的保留字。這些詞是工具接口,讓,包,私有,受保護,公開。靜態和屈服
有關更全面的列表,請查看以下MDN文檔:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
|
高度活躍的問題。贏得10個聲譽才能回答這個問題。信譽要求有助於保護該問題免受垃圾郵件和非答復活動的侵害。
不是您要找的答案?瀏覽標記為javascript語法jslint use-strict的其他問題,或提出您自己的問題。