javascript嚴格模式

概述

ECMAScript 5的嚴格模式是JavaScript中的一種限制性更強的變種方式。嚴格模式不是一個子集:它在語義上與正常代碼有着明顯的差別。不支持嚴格模式的瀏覽器與支持嚴格模式的瀏覽器行爲上也不同, 因此不要在未經嚴格模式特性測試狀況下使用嚴格模式。嚴格模式能夠與非嚴格模式共存,因此腳本能夠逐漸的選擇性加入嚴格模式。javascript

嚴格模式在語義上與正常的JavaScript有一些不一樣。 首先,嚴格模式會將JavaScript陷阱直接變成明顯的錯誤。其次,嚴格模式修正了一些引擎難以優化的錯誤:一樣的代碼有些時候嚴格模式會比非嚴格模式下更快。 第三,嚴格模式禁用了一些有可能在將來版本中定義的語法。html

若是你想讓你的JavaScript代碼在嚴格模式下運行,能夠參考轉換成嚴格模式java

開啓嚴格模式

做用於整個腳本文件

須要在全部語句以前放一個特定語句 "use strict"; (或 'use strict';)注意必須是腳本開始第一行,不然無效node

// 整個語句都開啓嚴格模式的語法
"use strict";
var v = "Hi!  I'm a strict mode script!";

合併不一樣模式的代碼文件成一個文件,須要特別注意:
這種語法存在陷阱,有一個大型網站已經被它坑倒了:不能盲目的合併衝突代碼。試想合併一個嚴格模式的腳本和一個非嚴格模式的腳本:合併後的腳本代碼看起來是嚴格模式。反之亦然:非嚴格合併嚴格看起來是非嚴格的。合併均爲嚴格模式的腳本或均爲非嚴格模式的都沒問題,只有在合併嚴格模式與非嚴格模式有可能有問題。建議按一個個函數去開啓嚴格模式(至少在學習的過渡期要這樣作)瀏覽器

做用於單個函數

一樣講'use strict';置於函數開始的第一行
測試生效:app

!function(){
    'use strict';
    x=1;
    console.log(x);    //因嚴格模式不容許未聲明的變量被賦值,會報錯
}();

報錯信息:函數

$ node 嚴格模式.js
D:\js\嚴格模式.js:3
        x=1;
         ^

ReferenceError: x is not defined

若是不是放在第一行沒有進入嚴格模式,結果會是1學習

嚴格模式有哪些不一樣

  • 不容許未聲明的變量被賦值(見上例)測試

  • 將拼寫錯轉成異常優化

    "use strict";
    // 假若有一個全局變量叫作mistypedVariable
    mistypedVaraible = 17; // 由於變量名拼寫錯誤,這一行代碼就會拋出 ReferenceError
  • 在嚴格模式下, 試圖刪除不可刪除的屬性時會拋出異常(以前這種操做不會產生任何效果):

    "use strict";
    delete Object.prototype; // 拋出TypeError錯誤
  • 對象字面量重複屬性名報錯
    正常模式下重名屬性是容許的,最後一個重名的屬性決定其屬性值。由於只有最後一個屬性起做用,當代碼是要改變屬性值而卻不是修改的最後一個重名屬性的時候,複製這個對象就產生一連串的bug。在嚴格模式下,重名屬性被認爲是語法錯誤:

    "use strict";
    var o = { p: 1, p: 2 }; // !!! 語法錯誤
  • 嚴格模式禁止八進制數字語法.
    測試以下:

    !function(){
        console.log(0123);                //八進制字面量不被容許
    }();

    報錯信息以下:

    $ node 嚴格模式.js
    D:\js\嚴格模式.js:19
            console.log(0123);                //八進制字面量不被容許
                        ^^^^
    SyntaxError: Octal literals are not allowed in strict mode.
  • 禁止使用with語句
    由於with語句沒法在編譯時就肯定,屬性到底歸屬哪一個對象。嚴格模式下, 使用 with 會引發語法錯誤, 因此就不會存在 with 塊內的變量在運行是才決定引用到哪裏的狀況了

    "use strict";
    var x = 17;
    with (obj) // !!! 語法錯誤
    {
      // 若是沒有開啓嚴格模式,with中的這個x會指向with上面的那個x,仍是obj.x?
      // 若是不運行代碼,咱們沒法知道,所以,這種代碼讓引擎沒法進行優化,速度也就會變慢。
      x;
    }
  • eval 獨立做用域
    在嚴格模式下 eval 僅僅爲被運行的代碼建立變量,eval做用域內再也不可以生成全局變量了,它所生成的變量只能用於eval內部。

    var x = 17;
    var evalX = eval("'use strict'; var x = 42; x");
    console.log(x === 17);        //true
    console.log(evalX === 42);        //true
  • 嚴格模式禁止刪除聲明變量。delete name 在嚴格模式下會引發語法錯誤:

    "use strict";
    
    var x;
    delete x; `// !!! 語法錯誤
  • this再也不指向全局對象
    一個開啓嚴格模式的函數,指定的this再也不被封裝爲對象,並且若是沒有指定this的話它值是undefined

    function fun() { return this; }
    console.log(fun() === undefined);    //true
    console.log(fun.call(2) === 2);        //true
    console.log(fun.apply(null) === null);        //true
    console.log(fun.call(undefined) === undefined);        //true
    console.log(fun.bind(true)() === true);        //true
  • arguments變爲參數的靜態副本
    嚴格模式下,函數的 arguments 對象會保存函數被調用時的原始參數。arguments[i] 的值不會隨與之相應的參數的值的改變而變化,同名參數的值也不會隨與之相應的 arguments[i] 的值的改變而變化。

    function f(a)
    {
      "use strict";
      a = 42;
      return [a, arguments[0]];
    }
    var pair = f(17);
    console.log(pair);    //[ 42, 17 ]

參考資料

MDN文檔
阮一峯老師的博客

相關文章
相關標籤/搜索