w3schools JavaScript中使用“嚴格”做什麼,背後的原因是什麼?




use strict作用 (17)

使用'use strict'; 不會突然使你的代碼變得更好。

JavaScript嚴格模式ECMAScript 5中的一項功能。 您可以通過在腳本/函數的頂部聲明這一點來啟用嚴格模式。

'use strict';

當JavaScript引擎看到此指令時 ,它將開始以特殊模式解釋代碼。 在這種模式下,當檢測到可能最終成為潛在錯誤的某些編碼實踐時(這是嚴格模式背後的原因),會引發錯誤。

考慮這個例子:

var a = 365;
var b = 030;

在他們對數字文字排列的痴迷中,開發人員無意中用八進製文字初始化了變量b 。 非嚴格模式會將其解釋為值為24的數字文字(在基數10中)。 但是,嚴格模式會拋出錯誤。

有關嚴格模式的非專業清單,請參閱此答案 。

我應該在哪裡使用'use strict';

  • 在我的 JavaScript應用程序中: 絕對! 當您使用代碼做一些愚蠢的事情時,嚴格模式可以用作舉報者。

  • 在我現有的 JavaScript代碼中: 可能不是! 如果您現有的JavaScript代碼具有嚴格模式下禁止的語句,則應用程序將會中斷。 如果您需要嚴格模式,則應準備好調試和更正現有代碼。 這就是使用'use strict'; 不會突然使你的代碼變得更好

我如何使用嚴格模式?

  1. 插入'use strict'; 在腳本之上的語句:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....
    

    請注意,文件myscript.js中的所有內容都將以嚴格模式進行解釋。

  2. 或者,插入'use strict'; 在函數體上的語句:

    function doSomething() {
        'use strict';
        ...
    }
    

    函數doSomething詞法範圍內的所有內容都將以嚴格模式進行解釋。 詞彙範圍這個詞在這裡很重要。 請參閱此答案以獲得更好的解釋。

嚴格模式禁止哪些事情?

我找到了一篇很好的文章,描述了嚴格模式下禁止的一些事情(請注意,這不是一個獨家列表):

範圍

從歷史上看,JavaScript一直困擾著函數的作用域。 有時它們似乎是靜態範圍的,但有些功能使它們的行為類似於動態範圍。 這令人困惑,使程序難以閱讀和理解。 誤解會導致錯誤。 這也是性能問題。 靜態作用域允許在編譯時發生變量綁定,但是對動態作用域的要求意味著必須將綁定延遲到運行時,這會帶來顯著的性能損失。

嚴格模式要求所有變量綁定都是靜態完成的。 這意味著必須消除或修改以前需要動態綁定的功能。 具體來說,刪除了with語句,並且eval函數篡改其調用者環境的能力受到嚴格限制。

嚴格的代碼的好處之一是像YUI Compressor這樣的工具在處理它時可以做得更好。

隱含的全局變量

JavaScript隱含了全局變量。 如果未顯式聲明變量,則會隱式聲明全局變量。 這使得初學者的編程更容易,因為他們可以忽略一些基本的家務雜務。 但它使較大程序的管理變得更加困難,並且顯著降低了可靠性。 因此,在嚴格模式下,不再創建隱含的全局變量。 您應該明確聲明所有變量。

全球洩漏

有許多情況可能導致this綁定到全局對象。 例如,如果您在調用構造函數時忘記提供new前綴,那麼構造函數將意外地綁定到全局對象,因此它不是初始化新對象,而是靜默地篡改全局變量。 在這些情況下,嚴格模式會this綁定到undefined ,這將導致構造函數拋出異常,從而允許更快地檢測到錯誤。

吵鬧失敗

JavaScript總是具有隻讀屬性,但是在ES5的Object.createProperty函數暴露該功能之前,您無法自己創建它們。 如果您嘗試將值分配給只讀屬性,則它將以靜默方式失敗。 賦值不會改變屬性的值,但是程序會像它一樣繼續進行。 這是一種完整性危害,可能導致程序進入不一致狀態。 在嚴格模式下,嘗試更改只讀屬性將引發異常。

八進制

當在字大小為3的倍數的機器上進行機器級編程時,數字的八進制(或基數8)表示非常有用。在使用CDC 6600大型機(字大小為60位)時,需要八進制。 如果你能讀八進制,你可以看一個單詞為20位數。 兩位數表示操作碼,一位數字表示8個寄存器中的一個。 在從機器代碼到高級語言的緩慢過渡期間,認為在編程語言中提供八進制形式是有用的。

在C中,選擇了非常不幸的八進製表示:前導零。 因此在C中, 0100表示64,而不是100,而08是錯誤,而不是8.更不幸的是,這種時代錯誤被複製到幾乎所有現代語言中,包括JavaScript,它只用於創建錯誤。 它沒有其他目的。 因此在嚴格模式下,不再允許八進制形式。

等等

參數偽數組在ES5中變得更像陣列。 在嚴格模式下,它會丟失其calleecaller屬性。 這使得可以將arguments傳遞給不受信任的代碼,而不會放棄大量的機密上下文。 此外,消除了函數的arguments屬性。

在嚴格模式下,函數文字中的重複鍵將產生語法錯誤。 函數不能有兩個具有相同名稱的參數。 函數不能具有與其參數之一具有相同名稱的變量。 函數無法delete自己的變量。 嘗試delete不可配置的屬性現在會拋出異常。 原始值不是隱式包裝的。

未來JavaScript版本的保留字

ECMAScript 5添加了一個保留字列表。 如果將它們用作變量或參數,則嚴格模式將引發錯誤。 保留字是:

implementsinterfaceletpackageprivateprotectedpublicstaticyield

進一步閱讀

https://code.i-harness.com

最近,我通過Crockford的JSLint運行了一些我的JavaScript代碼,它給出了以下錯誤:

第1行問題1:缺少“使用嚴格”聲明。

做一些搜索,我意識到有些人加上"use strict"; 進入他們的JavaScript代碼。 一旦我添加了語句,錯誤就會停止顯示。 不幸的是,谷歌沒有透露這個字符串聲明背後的歷史。 當然它必須與瀏覽器如何解釋JavaScript有關,但我不知道效果會是什麼。

那麼什麼是"use strict"; 一切,它意味著什麼,它仍然相關嗎?

當前任何瀏覽器都會響應"use strict"; 字符串或將來使用?


引自w3schools

“使用嚴格”指令

“use strict”指令是JavaScript 1.8.5(ECMAScript版本5)中的新指令。

它不是一個語句,而是一個文字表達式,被早期版本的JavaScript忽略。

“use strict”的目的是表明代碼應該以“嚴格模式”執行。

使用嚴格模式,您不能使用未聲明的變量。

為何選擇嚴格的模式?

嚴格模式可以更輕鬆地編寫“安全”JavaScript。

嚴格模式將以前接受的“錯誤語法”更改為實際錯誤。

例如,在普通的JavaScript中,錯誤輸入變量名稱會創建一個新的全局變量。在嚴格模式下,這將引發錯誤,從而無法意外創建全局變量。

在普通的JavaScript中,開發人員不會收到任何錯誤反饋,將值分配給不可寫屬性。

在嚴格模式下,對非可寫屬性,僅getter屬性,不存在的屬性,不存在的變量或不存在的對象的任何賦值都將引發錯誤。

請參閱http://www.w3schools.com/js/js_strict.asp了解更多信息


use strict 是一種讓你的代碼更安全的方法,因為你不能使用危險的功能,這些功能可能不會像你期望的那樣工作。並且在它使代碼更加嚴格之前被編寫。


我的兩分錢:

嚴格模式的目標之一是允許更快地調試問題。 它可以幫助開發人員在發生某些可能導致網頁無聲和奇怪行為的錯誤事件時拋出異常。 當我們使用use strict ,代碼會拋出錯誤,這有助於開發人員提前修復它。

use strict後我學到的幾件重要事情:

防止全局變量聲明:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

現在,此代碼在全局範圍內創建nameoftree ,可以使用window.nameoftree進行訪問。 當我們實現use strict ,代碼會拋出錯誤。

未捕獲的ReferenceError:未定義nameoftree

Sample

消除聲明:

使用uglify-js等工具無法縮小語句。 它們也deprecated並從未來的JavaScript版本中刪除。

Sample

防止重複:

當我們有重複屬性時,它會拋出異常

Uncaught SyntaxError:嚴格模式下不允許對象文字中的重複數據屬性

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

還有更多,但我需要獲得更多的知識。


嚴格模式對常規JavaScript語義進行了一些更改:

  • 通過更改它們以拋出錯誤來消除一些JavaScript無聲錯誤。

  • 修復了使JavaScript引擎難以執行優化的錯誤。

  • 禁止在ECMAScript的未來版本中定義某些語法。

了解更多信息vistit Strict Mode- Javascript


在ECMAScript 5中引入了JavaScript“嚴格”模式。

  (function() {
  "use strict";
   your code...
   })();

寫“使用嚴格”; 在JS文件的最頂層打開嚴格的語法檢查。它為我們完成以下任務:

(i)如果您嘗試分配未聲明的變量,則會顯示錯誤

(ii)阻止您覆蓋關鍵的JS系統庫

(ii)禁止一些不安全或容易出錯的語言功能

“use strict”也適用於個別功能。在代碼中包含“嚴格使用”總是更好的做法。

瀏覽器兼容性問題:“use”指令旨在向後兼容。不支持它們的瀏覽器只會看到一個未被進一步引用的字符串文字。所以,他們會過去並繼續前進。


如果您使用過去一年左右發布的瀏覽器,那麼它很可能支持JavaScript Strict模式。 只有在ECMAScript 5成為當前標準之前的舊瀏覽器才支持它。

命令周圍的引號確保代碼仍然可以在舊版瀏覽器中工作(儘管在嚴格模式下生成語法錯誤的事情通常只會導致腳本在這些舊版瀏覽器中以某種難以檢測的方式出現故障)。


我強烈建議每個開發人員現在開始使用嚴格模式。 有足夠的瀏覽器支持它,嚴格的模式將合法地幫助我們避免我們甚至不知道你的代碼中的錯誤。

顯然,在初始階段,我們以前從未遇到過錯誤。 為了獲得全部好處,我們需要在切換到嚴格模式後進行適當的測試,以確保我們已經捕獲了所有內容。 當然,我們不只是在代碼中拋出use strict並假設沒有錯誤。 所以,流失是時候開始使用這個非常有用的語言功能來編寫更好的代碼。

例如,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint是Douglas Crockford編寫的調試器。 只需粘貼您的腳本,它就會快速掃描代碼中的任何明顯問題和錯誤。


比較小例子:

非嚴格模式:

for (i of [1,2,3]) console.log(i)

// output:
// 1
// 2
// 3

嚴格模式:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

添加"use strict"; ,以下情況將在腳本執行之前拋出一個SyntaxError

  • 為未來的ECMAScript版本舖平道路 ,使用一個新保留的關鍵字(在ECMAScript 6預設中 ): implementsinterfaceletpackageprivateprotectedpublicstaticyield

  • 在塊中聲明函數

    if(a<b){ function f(){} }
    
  • 八進制語法

    var n = 023;
    
  • this一點指向全局對象。

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • 為對象文字中的屬性名稱聲明兩次相同的名稱

     {a: 1, b: 3, a: 7} 
    

    在ECMAScript 6中不再是這種情況( 錯誤1041128 )。

  • 使用相同的名稱函數聲明兩個函數參數

    f(a, b, b){}
    
  • 將值設置為未聲明的變量

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • 使用delete變量名稱delete myVariable;

  • 使用evalarguments作為變量或函數參數名稱

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 
    

資料來源:


這是ECMAScript 5的一個新功能.John Resig寫了一個很好的摘要

它只是一個放在JavaScript文件中的字符串(位於文件頂部或函數內部),如下所示:

"use strict";

現在將它放在你的代碼中不應該導致當前瀏覽器出現任何問題,因為它只是一個字符串。 如果您的代碼違反了編譯指示,將來可能會導致您的代碼出現問題。 例如,如果您當前有foo = "bar"而沒有先定義foo ,那麼您的代碼將開始失敗......在我看來這是一件好事。


這篇關於Javascript Strict Mode的文章可能會讓您感興趣: John Resig - ECMAScript 5 Strict Mode,JSON等

引用一些有趣的部分:

嚴格模式是ECMAScript 5中的一項新功能,允許您在“嚴格”操作上下文中放置程序或函數。 這種嚴格的上下文阻止了某些操作被採取並引發更多異常。

和:

嚴格模式有兩種方式:

  • 它捕獲了一些常見的編碼bloopers,拋出異常。
  • 當採取相對“不安全”的操作(例如獲取對全局對象的訪問權限)時,它會阻止或拋出錯誤。
  • 它會禁用令人困惑或經過深思熟慮的功能。

另請注意,您可以對整個文件應用“嚴格模式”...或者您只能將其用於特定功能(仍然引用John Resig的文章)

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

如果你必須混合舊代碼和新代碼,這可能會有所幫助;-)

所以,我認為它有點像你可以在Perl中"use strict""use strict" (因此名稱?) :通過檢測更多可能導致破壞的事情,它可以幫助您減少錯誤。

目前,它受到所有主流瀏覽器支持 (IE 9及以下版本)


“使用嚴格”; 是程序員不會使用JavaScript的鬆散或不良屬性的保險。這是一個指南,就像一個統治者將幫助你做直線。“使用嚴格”將幫助您進行“直接編碼”。

那些不喜歡使用標尺來直線行的人通常會在那些要求其他人調試代碼的頁面中結束。

相信我。與設計不良的代碼相比,開銷可以忽略不計。多年來一直擔任高級JavaScript開發人員的Doug Crockford在這裡發表了一篇非常有趣的帖子。就個人而言,我喜歡一直回到他的網站,以確保我不忘記我的良好做法。

現代JavaScript實踐應該始終喚起“使用嚴格”; 附註。ECMA集團選擇“嚴格”模式的唯一原因是允許經驗較少的編碼人員訪問JavaScript,然後有時間適應新的更安全的編碼實踐。


“嚴格使用”; 是ECMA努力使JavaScript更加強大。它引入了JS,試圖使其至少有一點“嚴格”(其他語言自90年代起實施嚴格的規則)。它實際上“迫使”JavaScript開發人員遵循某種編碼最佳實踐。JavaScript仍然非常脆弱。沒有類型變量,類型化方法等。我強烈建議JavaScript開發人員學習更強大的語言,如Java或ActionScript3,並在JavaScript代碼中實現相同的最佳實踐,它會更好地工作,更容易調試。


一些參與ECMAScript委員會的人員進行了很好的討論:JavaScript的變化,第1部分:ECMAScript 5“關於"use strict"交換機的增量使用如何允許JavaScript實施者清理JavaScript的許多危險特性而不會突然破壞每個網站在世界上。

當然,它還討論了很多這些錯誤的內容以及ECMAScript 5如何修復它們。


請注意,這use strict是在EcmaScript 5中引入的,並且從那時開始保留。

以下是在ES6ES7觸發嚴格模式的條件:

  • 全局代碼是嚴格模式代碼,如果它以包含使用嚴格指令的指令序言開頭(見14.1.1)。
  • 模塊代碼始終是嚴格的模式代碼。
  • ClassDeclarationClassExpression的所有部分都是嚴格模式代碼。
  • 如果Eval代碼以包含Use Strict Directive的Directive Prologue開頭,或者對eval的調用是嚴格模式代碼中包含的直接eval(見12.3.4.1),則Eval代碼是嚴格模式代碼。
  • 如果關聯的FunctionDeclaration,FunctionExpression,GeneratorDeclaration,GeneratorExpression,MethodDefinition或ArrowFunction包含在嚴格模式代碼中,或者產生函數[[ECMAScriptCode]]內部槽的值的代碼以指令序言開頭,則函數代碼是嚴格模式代碼包含使用嚴格指令。
  • 作為內置函數和生成器構造函數的參數提供的函數代碼是嚴格模式代碼,如果最後一個參數是一個String,處理時是一個以包含Use Strict指令的Directive Prologue開頭的FunctionBody

開發人員應該使用的主要原因"use strict"是:

  1. 防止意外聲明全局變量。"use strict()"使用var前將確保變量在使用前聲明。例如:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. 注意:該"use strict"指令僅在腳本或函數的開頭被識別。
  3. 該字符串"arguments"不能用作變量:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. 將限制使用關鍵字作為變量。試圖使用它們會引發錯誤。

簡而言之,這將使您的代碼不易出錯,反過來會讓您編寫好的代碼。

要了解更多信息,請參閱此處





use-strict