JS中的“use strict” 嚴格模式


1、介紹嚴格模式

2、嚴格模式影響范圍

  • 變量:  var、delete、變量關鍵字
  • 對象: 只讀屬性、 對象字面量屬性重復申明
  • 函數:參數重名、arguments對象、申明
  • 其他:this、eval、關鍵字...

嚴格模式

 ECMAScript 5 引入嚴格模式('strict mode')概念。通過嚴格模式,在函數內部選擇進行較為嚴格的全局或局部的錯誤條件檢測,使用嚴格模式的好處是可以提早知道代碼中的存在的錯誤,

及時捕獲一些可能導致編程錯誤的ECMAScript行為。在開發中使用嚴格模式能幫助我們早發現錯誤。

 

設立"嚴格模式"的目的,主要有以下幾個:錯誤檢測、規范、效率、安全、面向未來

  - 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;

  - 消除代碼運行的一些不安全之處,保證代碼運行的安全;

  - 提高編譯器效率,增加運行速度;

  - 為未來新版本的Javascript做好鋪墊。

 

進入"嚴格模式"的編譯指示(pragma),是下面這行語句:  

"use strict";  

這個語法從ECMAScript 3 開始支持。向后兼容不支持嚴格模式的瀏覽器,他們就當遇到了一個普通字符串,編譯時忽略。

  

將"use strict"放在腳本文件的第一行,則整個腳本都將以"嚴格模式"運行。

如果這行語句不在第一行,則無效,整個腳本以"正常模式"運行。

如果不同模式的代碼文件合並成一個文件,這一點需要特別注意。

(嚴格地說,只要前面不是產生實際運行結果的語句,"use strict"可以不在第一行,比如直接跟在一個空的分號后面。) 

<script>  
  "use strict";  
  console.log("這是嚴格模式。");  
</script>  
<script>  
 console.log("這是正常模式。");  
</script>  

將"use strict"放在函數體的第一行,則整個函數以"嚴格模式"運行。 

function strict(){  
  "use strict";  
  return "這是嚴格模式。";  
}  
function notStrict() {  
  return "這是正常模式。";  
}  
 

 建議只在特定的作用域中使用嚴格模式。放在全局作用域中(函數外部),頁面的其他腳本也都處於嚴格模式下。因為上面的調用方法不利於文件合並,所以更好的做法是,下面的方法,將整個腳本文件放在一個立即執行的函數表達式IIFE之中。 

+function (){  "use strict";  
  
}();  

 

變量

非嚴格模式下,a = 1可以創建一個全局變量。

嚴格模式下,變量都必須先用var命令顯示聲明,然后再使用。 嚴格模式不允許意外創建的全局變量(示例),否則會報錯(Uncaught ReferenceError: v is not defined )。

"use strict";  
v = 1; // 報錯,v未聲明  
for(i = 0; i < 2; i++) { // 報錯,i未聲明 ReferenceError  
  
}  

而且,嚴格模式不能對變量調用 delete 操作符(示例),會導致錯誤(Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. )。

非嚴格模式允許這樣操作,但返回false 。

 

別用這些詞做 變量名 或 參數名 implements, interface, let, package, private, protected, public, static, yield。

這些都是保留字,將來ECMAScript 版本中可能會用到他們。

嚴格模式下作為其保留關鍵字,使用這些標識符作為變量名會導致語法錯誤。

function package(protected){ // 報錯!  
  "use strict";  
  var implements; // 報錯!  
  
  interface: // 報錯!  
  while (true){  
    break interface; // 報錯!  
  }  
  
  function private() { } // 報錯!  
}  
function fun(static) { 'use strict'; } // 報錯!  

對象

為只讀屬性賦值報錯(示例

"use strict"  
var testObj = Object.defineProperties({}, {  
  prop1: {  
      value: 10,  
      writable: false // by default  
  },  
  prop2: {  
      get: function () {  
      }  
  }  

對象字面量同一個屬性重復賦值(Uncaught SyntaxError: Unexpected identifier),非嚴格模式會取最后一個(示例

 

"use strict"  
var person = {  
  name : "Tom"  
  name : "Cat"  
}  

 

另外兩種情況:

為不可配置的屬性使用delete操作符會拋出typeError

為不可擴展的對象添加屬性會拋出TypeError

 

函數

嚴格模式下參數名不能重復(Uncaught SyntaxError: Strict mode function may not have duplicate parameter names)(示例

非嚴格模式,函數內部實際訪問的是第二個參數,要訪問第一個參數必須通過arguments對象

"use strict"  
 function sum(num, num) {}  

非嚴格模式下,修改命名參數值也會反映到arguments對象中,

嚴格模式下者兩個值是完全獨立的。(示例)

"use strict"  
function showValue(value) {  
    value = "Foo"  
    alert(value)        // Foo  
    alert(arguments[0]) // 嚴格模式 hi  
                        // 非嚴格模式 Foo  
}  
  
showValue("hi")  
 嚴格模式也淘汰了arguments.callee(引用函數本身)和arguments.caller(引用函數調用函數)

不允許非頂層的函數。也就是,只能在腳本的頂級和在函數內部申明函數,if for等語句中申明函數會導致語法錯誤。

"use strict";  
if (true){  
  function f() { } // 報錯! syntax error  
  f();  
}  
  
for (var i = 0; i < 5; i++){  
  function f2() { } // 報錯! syntax error  
  f2();  
}  
  
function baz(){ // kosher  
  function eit() { } // also kosher  
}  

this

嚴格模式下抑制this

(function(){ return this; })()
 
Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
(function(){ 'use strict'; return this; })()
undefined

其他

去掉了with。

數字前面別加0。因為...禁用八進制算法。因為八進制不包含在ECMAScript中,數字前面的0會改變數字的含義,js會認為是一個八進制數,從而報錯。 

"use strict";  
var sum = 015 + // 報錯! syntax error  
          197 +  
          142;  

還有其他例子

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FFunctions_and_function_scope%2FStrict_mode

 

 參考資料:
http://msdn.microsoft.com/zh-cn/library/br230269(v=vs.94).aspx


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM