JavaScript Strict Mode
語意上的修正:
- Slient Error → Throw Actual Error。
- 修正會影響 JavaScript 引擎最佳化的錯誤 (Mistake)。有時程式在 Strict Mode 執行效率較高。
- 禁用未來可能會被加入 ECMAScript 的語法作為變量/屬性/function 名稱。
優點
-
Securing JavaScript。
Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users. JavaScript in browsers can access the user's private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript's flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.
-
為未來版本的 ECMAScript 做準備。
使用方式
-
在文件上寫
"use strict",作用於全文件內。-
如果同時引用 a.js 及 b.js,僅在 a.js 撰寫
"use strict",且 a.j 引用先於 b.js,strict mode 僅作用於 a.js 內。 -
This syntax has a trap that has already bitten a major site: it isn't possible to blindly concatenate non-conflicting scripts. Consider concatenating a strict mode script with a non-strict mode script: the entire concatenation looks strict! The inverse is also true: non-strict plus strict looks non-strict. Concatenation of strict mode scripts with each other is fine, and concatenation of non-strict mode scripts is fine. Only concatenating strict and non-strict scripts is problematic. It is thus recommended that you enable strict mode on a function-by-function basis (at least during the transition period).
-
-
在 function scope 寫
"use strict",作用於 function scope 內。 -
Module 必為 strict mode
//宣告先於 use strict, 因此不會報錯 var let = 1; "use strict"; //宣告後於 use strict, 因此報錯 var class = 2;
FEATURES
Properties and Variables
-
不可設定值給未宣告的變數。
"use strict"; //Throw ReferenceError a = 123; -
不可賦值給 non-writable 的變數/屬性。
"use strict"; let idCard = { name: "許祐誠" }; Object.defineProperty(idCard, "num", { value: "ABCD1234", writable: false }); //Throw TypeError idCard.num = "BBB"; -
不可
deleteundeletable 的變數/屬性。- Prototype
-
以 literal 方式宣告 Object 時,其中的屬性名稱不可重複。
"use strict"; //Throw Error const person1 = { name: "Maw", name: "Arren" } -
function 的 parameter name 必須為唯一。
"use strict"; //Throw Error function hello(name, name) { //... } -
不可設定屬性給 Primitive Value。
"use strict"; var idCard = 12345; //Throw TypeError idCard.name = "許祐誠" -
不可使用 syntax (包括未來的 ECMAScript syntax) 關鍵字作為變量/屬性名稱。
arguments、eval、class、const、let⋯等。
Syntax
-
0*及"\*"的 octal syntax 禁用,須改用 ECMAScript 5 的0o-*syntax。"\045" === "%"→0o045 === "%"
-
禁用
withsyntax。 -
eval不添加變量至 scope。eval自成一個 Block{}
//Sloppy Mode var x = 17; eval("var x = 42;"); //Result is false; console.log(x === 17); //Strict Mode "use strict"; var x = 17; eval("var x = 42;"); //Result is true; console.log(x === 17); -
不能
deleteplain names。"use strict"; var a = "A"; //Throw SyntaxError delete a; function testDelete() { var b = "A"; //Throw SyntaxError delete b; }
function 中的 arguments
-
不可
delete arguments -
在 function 中,如果參數在 scope 內被修改了,其相對應的
arguments不會跟著修改。"use strict"; function hello (name) { name = "Maw"; console.log(`Hello, ${name} (name)`); console.log(`Hello, ${arguments[0]} (arguments[0])`) } hello("Arren"); //Hello, Maw (name) //Hello, Arren (arguments[0]) -
不支援
arguments.callee。arguments.callee:當前正在執行的 function 本身。
-
不支援
arguments.caller。
Logic
-
當 function 與
null、Boolean、undefined進行綁定時(call、apply、bind);或 function 屬於 global scope 時, function 的this為null。"use strict"; function testThis() { return this; } testThis();//回傳 null testThis.call(false);//回傳 null testThis.call(true);//回傳 null testThis.apply(null);//回傳 null testThis.bind(undefined)();//回傳 null -
不可在判斷語句中宣告 function (測不出來)
"use strict"; if (true) { //SyntaxError function f() {} f(); } for (let i = 0; i < 5; i++) { //SyntaxError function f() {} f(); }