摘要:字符串不能用作標識符變量或函數名參數名等在嚴格模式下,函數聲明無法嵌套在語句或塊中。嚴格模式下用法無效如果在函數內聲明變量,則不能在此函數外部使用該變量。在嚴格模式下,更改的值不會影響的值,因為對象只是一個本地副本。
什么是嚴格模式本文同步自 我的博客,地址:http://reeoo.me/archives/strictmode.html
我們平時寫的JavaScript代碼一般都運行在正常模式中的,除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)。看名字就知道,這種模式會讓JavaScript在更嚴格的環境中運行。
包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱。(github上面好多項目都是用的嚴格模式)
啟用嚴格模式 為整個腳本啟用嚴格模式在所有語句之前放一個特定語句 "use strict",假設有一個腳本reeoo.js,可以這樣開啟嚴格模式:
"use strict"; var name = "Reeoo"; console.log(name);
BUT這種寫法存在天然的坑,假如我們要做代碼合并,我現在要把heigui.js:
heigui = "db";
和reeoo.js進行合并,本來兩個腳本分開執行是好好的,合起來就會報錯。
Uncaught ReferenceError: heigui is not defined(…)
一個嚴格模式的腳本和一個非嚴格模式的腳本合并可能會導致非嚴格模式的腳本代碼報錯,建議代碼都包在一個立即執行函數里面。
(function(){ "use strict"; var name = "reeoo"; })(); (function(){ heigui = "db"; })();
這樣合并之后就不會報錯了。
為某個函數啟用嚴格模式要給某個函數開啟嚴格模式,得把"use strict"; 聲明放在函數體所有語句之前就行了。
function strictFun() { // 函數級別嚴格模式語法 "use strict"; console.log("I am a strictmode function!"); } function normalFun() { console.log("I am a mormal function!"); }Chrome中調試嚴格模式
我有這么一段代碼:
"use strict" name = "reeoo"; console.log(name)
把這段代碼直接粘貼到Chrome的控制臺中執行,正常情況下應該報錯,但是并沒有報錯,
很顯然,嚴格模式下變量不適用var聲明是不合法的,但是為什么沒有報錯?
這是什么鬼,難道Chrome不支持嚴格模式?開什么玩笑。。。
網上搜了一下,原來Chrome的控制臺的代碼是運行在eval之中的,你沒法對eval函數使用嚴格模式(應該也不完全對,但是具體Chrome做了什么,不得而知),下圖說明eval函數可以使用嚴格模式:
要想在Chrome瀏覽器中對嚴格模式正常報錯,需要在代碼外層套一個立即執行函數,或者其它類似的措施。
(function(){ "use strict" name = "reeoo"; console.log(name) })()
這樣就可以了
FireFox代碼草稿紙調試嚴格模式Chrome非要我們包一層閉包才能跑嚴格模式,既然這么麻煩,有沒有別的方式可以直接跑嚴格模式的代碼呢?
FireFox有一個代碼草稿紙可以直接跑,快捷鍵SHIFT+F4
嚴格模式到底有多嚴格 嚴格模式中一些重要的限制1. 變量聲明
不允許使用一個沒有聲明的變量
"use strict"; name = "reeoo";
報錯(代碼草稿紙,下同)
Exception: ReferenceError: assignment to undeclared variable name
2. 修改只讀屬性的值
"use strict"; var testObj = Object.defineProperties({}, { prop1: { value: 10, writable: false // 一個只讀的屬性 }, prop2: { get: function () { } } }); testObj.prop1 = 20; //嘗試改變prop1的值 testObj.prop2 = 30;//嘗試改變prop2的值
嚴格模式下會報錯:
Uncaught TypeError: Cannot assign to read only property "prop1" of #
非嚴格模式頂多就是值賦不上去而已,并不會報錯
3. 修改不可擴展的屬性
表現為將屬性添加到 extensible 屬性設置為 false 的對象。
"use strict"; var testObj = new Object(); Object.preventExtensions(testObj);//經過這個方法處理過的對象,不影響原有對象的刪除,修改.但是無法添加新的屬性成員了. testObj.name = "reeoo";
嚴格模式報錯:
Uncaught TypeError: Can"t add property name, object is not extensible
非嚴格模式不會報錯,但是testObj也不會被擴展。
4. 刪除變量、函數或參數
刪除 configurable 特性設置為 false 的屬性。
"use strict"; var testvar = 15,testObj={}; function testFunc() {}; delete testvar; delete testFunc; Object.defineProperty(testObj, "testvar", { value: 10, configurable: false }); delete testObj.testvar;
報錯:
Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
5. 在一個對象文本中多次定義某個屬性
嚴格模式下不允許一個屬性有多個定義
"use strict"; var testObj = { prop1: 10, prop2: 15, prop1: 20 };
報錯(node控制臺)
Duplicate data property in object literal not allowed in strict mode
正常模式中后聲明的重復的變量會覆蓋前面聲明的,而且不會報錯。
注:這個問題在ECMAScript6中已被修復。
6. 嚴格模式下不允許形參參數名稱重復
"use strict"; function testFunc(param1, param1) { return 1; };
報錯:
Uncaught SyntaxError: Duplicate parameter name not allowed in this context
7. 無法使用標識符的未來保留字,嚴格模式下將保留標識符名稱
一下標識符(ES6中依然沒有實現的)在嚴格模式中是不能使用的,否則也會報錯。
用了就是這個下場:
Uncaught SyntaxError: Unexpected strict mode reserved word
implements interface package private protected public static yield
8. 嚴格模式下不允許使用八進制數字參數和轉義字符
"use strict"; var testoctal = 010; var testescape =