1. 程式人生 > >JavaScript嚴格模式與非嚴格模式區別

JavaScript嚴格模式與非嚴格模式區別

開啟嚴格模式方法"use strict";, 如果放在檔案開頭就是全域性開啟嚴格模式, 還可以在函式內宣告, 這麼做的話就是這個函式開啟嚴格模式.

  1. 嚴格模式下無法再意外建立全域性變數。在普通的JavaScript裡面給一個拼寫錯誤的變數名賦值會使全域性物件新增一個屬性。嚴格模式中意外建立全域性變數被丟擲錯誤替代:
"use strict";
a = 1; // 報錯, 因為找不到a的宣告
  1. 在嚴格模式下, 試圖刪除不可刪除的屬性時會丟擲異常
"use strict";
delete Object.prototype; // 丟擲TypeError錯誤, 如果不是在嚴格模式會返回false, 不會報錯
  1. , 嚴格模式要求函式的引數名唯一. 在正常模式下, 最後一個重名引數名會掩蓋之前的重名引數. 之前的引數仍然可以通過 arguments[i] 來訪問, 還不是完全無法訪問.
function sum(a, a, c){ // !!! 語法錯誤
  "use strict";
  return a + a + c; // 程式碼執行到這裡會出錯 Uncaught SyntaxError: Duplicate parameter name not allowed in this context
}
  1. 嚴格模式禁止八進位制數字語法. 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.
  1. 嚴格模式禁用 with
  2. 嚴格模式下的 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
  1. 嚴格模式禁止刪除宣告變數.;
"use strict";

var x = 1;
delete x; // !!! 語法錯誤 Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. 如果是非嚴格模式, 返回false
  1. 嚴格模式下,引數的值不會隨 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
  1. 不再支援arguments.callee. 正常模式下,arguments.callee 指向當前正在執行的函式.
  2. 在嚴格模式下通過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物件 
  1. 在嚴格模式下,那麼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