“use strict” 嚴格模式使用(前端基礎系列)


ECMAscript5添加一種嚴格模式的運行模式("use strict"),讓你的js語句在更加嚴格的環境下進行運行;

一、主要作用:

  1. 消除版本javascript中一些不合理及不嚴謹之處,減少怪異行為
  2. 提高編譯效率,提高運行速度
  3. 為新版本的javasript做鋪墊兼容

二、如何使用
啟動嚴格模式的標志就是,在開頭第一行中添加"use strict"字符串,在低版本的瀏覽器,或是說js引擎中,只是把這個標志當做一句字符串而已,而支持ES5的瀏覽器會進行啟動“嚴格模式”;具體有兩種調用方式:

  1. 針對整個腳本文件有效
    在js文件的第一行中添加"use strict",或是在<script>標簽中第一行添加標志,則所有后面的語句在嚴格模式下進行執行;注意,所謂的第一行,表示在 "use strict" 語句之前沒有可執行的有效語句(可以在空的分號后面);當使用合並壓縮工具時,就要特別注意;
    <script type="text/javascript"> 
        "use strict";
        // 嚴格模式
        // do something
        
    </script>
    
    <script type="text/javascript"> 
        // 非嚴格模式
        // do something
        
    </script>

     

  2. 針對單個函數有效
    將 "use strict" 放在函數的第一行,則整個函數有效
    function strict(){
        "use strict";
         // 嚴格模式
        // do something
    }

     

  3. 更加通用的寫法,由於第一種方法,不利於文件的合並,根據針對函數的形式,可以將腳本文件包裹在一個自執行的匿名函數中,這樣相當於所有語句都在一個嚴格模式的函數中執行
    (function(){
        "use strict";
        // 嚴格模式
        // do something
    }())

三、語法與行為變更

  1. 全局變量的顯示聲明
    正常模式下,對於使用沒有進行聲明的變量,編譯時默認改變量為全局變量(添加到window對象的屬性中,可以使用delete進行刪除),而嚴格模式下進行了限制,使用變量前必須聲明(var/let/const);
    function strict(){
        "use strict";
         name = "ukerxi";
         console.log(name);
    }
    
    function noStrict(){
         name = "ukerxi";
         console.log(name);
    }
    
    // 執行函數
    strict(); // 報 Uncaught ReferenceError: name is not defined(引用錯誤)
    noStrict(); // ==> 'ukerxi'

 

  1. 禁止使用with語句
    正常模式下with語句允許當前代碼執行在新的變量對象中,即改變了執行環境;在嚴格模式下,已經禁止使用with語句,由於只有運行時才知道語句的執行環境,所以執行非常耗時緩慢;
    var foo = {
      name: "ukerxi",
      hobby: 'no'
    };
    
    with(foo){
      console.log(name); // ==> 'ukerxi'
    }

     

  1. 創設eval的作用域
    正常模式下,Javascript語言有兩種變量作用域(scope):全局作用域和函數作用域。嚴格模式創設了第三種作用域:eval作用域。
    正常模式下,eval語句的作用域,取決於它處於全局作用域,還是處於函數作用域。嚴格模式下,eval語句本身就是一個作用域,不再能夠生成全局變量了,它所生成的變量只能用於eval內部;
    "use strict";
    var name = 'ukerxi';
    eval('var name = "originEval";');
    console.log(name); // ==> "ukerxi"

    但是存在一種情況,就是當你使用變量進行緩存eval函數時,再使用緩存變量進行執行操作,會產生正常模式下執行eval函數的效果(暫時不知道這個bug是語言本身的設計,還是其他原因導致的)

    "use strict";
    var name = 'ukerxi';
    var globalEval = eval; // 緩存一個全局的eval函數
    eval('var name = "originEval";');
    console.log(name); // ==> "ukerxi" 
    
    // 使用緩存進行執行函數,會導致變更作用域
    globalEval('var name = "globalEval";');
    console.log(name); // ==> "globalEval"

     

  1. 禁止this執行全局對象,默認指向undefined
    "use strict";
    console.log(this); // ==> undefined

     

  2. 禁止使用arguments.caller和arguments.callee進行調用自身及被調用函數
    "use strict";
    function testHandle(){
        console.log(arguments.caller); // 報錯
        console.log(arguments.callee); // 報錯
    }

     

  3. 禁止修改arguments變量參數對象,arguments不再追蹤參數的變化
    "use strict";
    function testHandle(){
       arguments = "test"; // 報語法錯誤
    }
  4. 禁止刪除變量
    "use strict";
    var name = "ukerxi";
    delete name; // 報錯
  5. 重名錯誤(函數參數重名&&對象重名屬性)
    "use strict";
    // 屬性重名報錯
    var testObj = {
        name: "ukerxi",
        name: "test"
    };
    
    // 參數重名報錯
    function testHandle(a, a, b){
        // do something
    }

     

  6. 禁止八進制表示法
    "use strict";
    var n = 0100; // 語法錯誤


  7. 函數必須聲明在頂層
    Javascript的新版本會引入"塊級作用域"。為了與新版本接軌,嚴格模式只允許在全局作用域或函數作用域的頂層聲明函數。也就是說,不允許在非函數的代碼塊內聲明函數
    "use strict";
    if (true) {
      function f() { } // 語法錯誤
    }
    for (var i = 0; i < 5; i++) {
      function f2() { } // 語法錯誤
    }

     

  8. 針對對象的操作,對於聲明只讀屬性的對象不可修改,刪除不可刪除的屬性報錯
    "use strict";
    var foo = {};
    // 只讀屬性的對象不可修改
    Object.defineProperty(foo, "v", { value: 1, writable: false });
    foo.v = 2; // 報錯
    
    // 刪除不可刪除的屬性報錯
    delete Object.prototype; // 報錯
    
    // 嚴格模式下,對一個使用getter方法讀取的屬性進行賦值,會報錯
    var foo1 = {
      get v() { return 1; }
    };
    foo1.v = 2; // 報錯
    
    
    // 嚴格模式下,對禁止擴展的對象添加新屬性,會報錯。
    var foo2 = {};
    Object.preventExtensions(foo2);
    foo2.v = 2; // 報錯

     

  9. 保留字
    為了向將來Javascript的新版本過渡,嚴格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。(主要是與類有關的保留字,和java類的關鍵字)

 

【參考鏈接】

  1. 阮一峰個人博客:http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html

【結束語】

   系列文章,包括了原創,翻譯,轉載等各類型的文章;一方面是為了自己總結,另一方面頁希望可以共享知識;在技術方面有輸入,也要有所輸出,才能更進一步!文章基於自己的實踐、閱讀及理解,如有不合理及錯誤的地方,煩請各大佬評論指出,以便改正,感謝!

 
       


免責聲明!

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



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