JavaScript嚴格模式與非嚴格模式區別
阿新 • • 發佈:2018-12-23
開啟嚴格模式方法"use strict";
, 如果放在檔案開頭就是全域性開啟嚴格模式, 還可以在函式內宣告, 這麼做的話就是這個函式開啟嚴格模式.
- 嚴格模式下無法再意外建立全域性變數。在普通的JavaScript裡面給一個拼寫錯誤的變數名賦值會使全域性物件新增一個屬性。嚴格模式中意外建立全域性變數被丟擲錯誤替代:
"use strict";
a = 1; // 報錯, 因為找不到a的宣告
- 在嚴格模式下, 試圖刪除不可刪除的屬性時會丟擲異常
"use strict";
delete Object.prototype; // 丟擲TypeError錯誤, 如果不是在嚴格模式會返回false, 不會報錯
- , 嚴格模式要求函式的引數名唯一. 在正常模式下, 最後一個重名引數名會掩蓋之前的重名引數. 之前的引數仍然可以通過 arguments[i] 來訪問, 還不是完全無法訪問.
function sum(a, a, c){ // !!! 語法錯誤
"use strict";
return a + a + c; // 程式碼執行到這裡會出錯 Uncaught SyntaxError: Duplicate parameter name not allowed in this context
}
- 嚴格模式禁止八進位制數字語法. ECMAScript並不包含八進位制語法, 但所有的瀏覽器都支援這種以零(0)開頭的八進位制語法:
0644 === 420
"\045" === "%"
.在ECMAScript 6中支援為一個數字加"0o"的字首來表示八進位制數.
var a = 0o10; // ES6: 八進位制
------------------
"use strict";
var a = 015 + // !!! 語法錯誤 Uncaught SyntaxError: Octal literals are not allowed in strict mode.
- 嚴格模式禁用 with
- 嚴格模式下的 eval 不再為上層範圍(surrounding scope,注:包圍eval程式碼塊的範圍)引入新變數.
var x = 1;
eval("var x = 2");
console.log(x); // 2
---------------
var x = 1;
eval(" 'use strict'; var x = 2")
console.log(x); // 1
- 嚴格模式禁止刪除宣告變數.;
"use strict";
var x = 1;
delete x; // !!! 語法錯誤 Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. 如果是非嚴格模式, 返回false
- 嚴格模式下,引數的值不會隨 arguments 物件的值的改變而變化. 嚴格模式下,函式的 arguments 物件會儲存函式被呼叫時的原始引數.
function f(a){
a = 42;
console.log(a, arguments[0]);
}
var pair = f(17); // 42 42
----------
function f(a){
"use strict";
a = 42;
console.log(a, arguments[0]);
}
var pair = f(17); // 42 17
- 不再支援
arguments.callee
. 正常模式下,arguments.callee
指向當前正在執行的函式. - 在嚴格模式下通過
this
傳遞給一個函式的值不會被強制轉換為一個物件。對一個普通的函式來說,this
總會是一個物件:不管呼叫時this
它本來就是一個物件;還是用布林值,字串或者數字呼叫函式時函式裡面被封裝成物件的this
;還是使用undefined
或者null
呼叫函式式this
代表的全域性物件(使用call
,apply
或者bind
方法來指定一個確定的this
) 對於一個開啟嚴格模式的函式,指定的this
不再被封裝為物件,而且如果沒有指定this
的話它值是undefined
;
"use strict";
function fun() { return this; }
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
-----------------
function fun() { return this; }
console.log(fun()); // window物件
console.log(fun.call(2)); // Number(2) 封箱的數字2
console.log(fun.apply(null)); // window物件
console.log(fun.call(undefined)); // window物件
console.log(fun.bind(true)()); // Boolean物件
- 在嚴格模式下,那麼fun.caller和fun.arguments都是不可刪除的屬性而且在存值、取值時都會報錯;
function restricted()
{
"use strict";
restricted.caller; // 丟擲型別錯誤 Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
restricted.arguments; // 丟擲型別錯誤
}
function privilegedInvoker()
{
return restricted();
}
privilegedInvoker();
------------
function restricted()
{
restricted.caller; // 返回privilegedInvoker函式
restricted.arguments; // 返回arguments
}
function privilegedInvoker()
{
return restricted();
}
privilegedInvoker();
參考連結
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode