嚴格模式程序員
除了正常的運行模式,JavaScript 還有第二種運行模式:嚴格模式(strict mode)。顧名思義,這種模式採用更加嚴格的 JavaScript 語法安全
一樣的代碼,在正常模式和嚴格模式中,可能會有不同的運行結果。函數
一些在正常模式下能夠運行的語句,在嚴格模式下將不能運行。this
- 設計目的
- 早期的 JavaScript 語言有不少設計不合理的地方,可是爲了兼容之前的代碼,又不能改變老的語法,
- 只能不斷添加新的語法,引導程序員使用新語法
- 嚴格模式是從 ES5 進入標準的,主要目的有如下幾個。
- 明確禁止一些不合理、不嚴謹的語法,減小 JavaScript 語言的一些怪異行爲
- 增長更多報錯的場合,消除代碼運行的一些不安全之處,保證代碼運行的安全
- 提升編譯器效率,增長運行速度
- 爲將來新版本的 JavaScript 語法作好鋪墊
進入嚴格模式的標誌,是一行字符串 use strict;spa
-
- 在整個腳本文件 啓用
- 放在腳本文件的第一行,整個腳本都將以嚴格模式運行。
-
<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)的屬性賦值,會報錯
-
- 函數禁止使用 fn.callee fn.caller
-
- 禁止使用 arguments.callee、arguments.caller
- 只有對象的屬性,且屬性的描述對象的 configurable 屬性設置爲 true,才能被 delete 命令刪除
- 靜態綁定
-
-
- 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等