(81)Wangdao.com第十六天_JavaScript 嚴格模式

嚴格模式程序員

除了正常的運行模式,JavaScript 還有第二種運行模式:嚴格模式(strict mode)。顧名思義,這種模式採用更加嚴格的 JavaScript 語法安全

一樣的代碼,在正常模式和嚴格模式中,可能會有不同的運行結果。函數

一些在正常模式下能夠運行的語句,在嚴格模式下將不能運行。this

 

  • 設計目的
    • 早期的 JavaScript 語言有不少設計不合理的地方,可是爲了兼容之前的代碼,又不能改變老的語法,
    • 只能不斷添加新的語法,引導程序員使用新語法
    • 嚴格模式是從 ES5 進入標準的,主要目的有如下幾個。
      • 明確禁止一些不合理、不嚴謹的語法,減小 JavaScript 語言的一些怪異行爲
      • 增長更多報錯的場合,消除代碼運行的一些不安全之處,保證代碼運行的安全
      • 提升編譯器效率,增長運行速度
      • 爲將來新版本的 JavaScript 語法作好鋪墊

 

  • 啓用方法

進入嚴格模式的標誌,是一行字符串 use strict;spa

  • 'use strict';
    • 在整個腳本文件 啓用
      • 放在腳本文件的第一行,整個腳本都將以嚴格模式運行。
      • <script>
            'use strict';
            console.log('這是嚴格模式');
        </script>
        
        <script> console.log('這是正常模式'); </script>

         

    • 只在單個函數中 啓用
      • use strict; 放在函數體的第一行,則整個函數以嚴格模式運行

 

    • 有時,須要把不一樣的腳本合併在一個文件裏面。
      • 若是一個腳本是嚴格模式,另外一個腳本不是,它們的合併就可能出錯。
        • 嚴格模式的腳本在前,則合併後的腳本都是嚴格模式
        • 若是正常模式的腳本在前,則合併後的腳本都是正常模式

 

      • 這時能夠考慮把整個腳本文件放在一個當即執行的匿名函數之中
        (function () {
            'use strict';
            // some code here
        })();

         

 

  • 顯示報錯

格模式使得 JavaScript 的語法變得更嚴格,更多的操做會顯式報錯設計

其中有些操做,在正常模式下只會默默地失敗,不會報錯code

    • 只讀屬性不可寫
      • 嚴格模式下,設置字符串的 length 屬性,會報錯    // TypeError: Cannot assign to read only property 'length' of string 'abc'
      • 刪除不可配置(non-configurable)屬性都會報錯

 

    • 禁止擴展的對象不可擴展
      • 嚴格模式下,對禁止擴展的對象添加新屬性,會報錯
        'use strict';
        var obj = {};
        Object.preventExtensions(obj);
        
        
        obj.v = 1;    // Uncaught TypeError: Cannot add property v, object is not extensible

 

    • 嚴格模式下,對一個只有取值器(getter)、沒有存值器(setter)的屬性賦值,會報錯

 

    • eval、arguments 不可用做標識名

 

    • 函數不能有重名的參數

 

    • 禁止八進制的前綴0表示法

 

  • 加強的安全措施
    • 全局變量必須顯式聲明

 

    • 禁止 this 關鍵字指向全局對象

 

    • 函數禁止使用 fn.callee    fn.caller

 

    • 禁止使用 arguments.callee、arguments.caller
      • 只有對象的屬性,且屬性的描述對象的 configurable 屬性設置爲 true,才能被 delete 命令刪除

 

    • 禁止刪除window 的變量

 

  • 靜態綁定
        • JavaScript 語言的一個特色,就是容許 「動態綁定」,
        • 即某些屬性和方法到底屬於哪個對象,不是在編譯時肯定的,而是在運行時(runtime)肯定的。
        • 某些狀況下,只容許靜態綁定。也就是說,屬性和方法到底歸屬哪一個對象,必須在編譯階段就肯定。
        • 這樣作有利於編譯效率的提升,也使得代碼更容易閱讀,更少出現意外。

 

    • 禁止使用 with 語句
      • 由於with語句沒法在編譯時就肯定,某個屬性到底歸屬哪一個對象,從而影響了編譯效果

 

    • 創設 eval 做用域

      • 正常模式下,JavaScript 語言有兩種變量做用域(scope):全局做用域和函數做用域
      • 嚴格模式創設了第三種做用域:eval做用域
      • eval 所生成的變量只能用於 eval 內部
        • (function () {
              'use strict';
              var x = 2;
              console.log(eval('var x = 5; x'))    // 5
              console.log(x)    // 2
          })()

           

      • 若是但願 eval 語句也使用嚴格模式,有兩種方式
        • // 方式一
          function f1(str){
              'use strict';
              return eval(str);
          }
          
          f1('undeclared_variable = 1');    // 報錯
          
          
          
          // 方式二
          function f2(str){
              return eval(str);
          }
          
          f2('"use strict";undeclared_variable = 1')     // 報錯

           

      • arguments 再也不追蹤參數的變化 
        • 變量arguments表明函數的參數。嚴格模式下,函數內部改變參數與arguments的聯繫被切斷了,二者再也不存在聯動關係

 

    • 非函數代碼塊不得聲明函數

      • 只容許在全局做用域或函數做用域聲明函數

 

    • 保留字
      • implements、interface、let、package、private、protected、public、static、yield等
相關文章
相關標籤/搜索