📓
Something About JavaScript
  • Introduction
  • Day 1:前言
  • Day 2:資料型態的夢魘——動態型別加弱型別(1)
  • Day 3:資料型態的夢魘——動態型別加弱型別(2)
  • Day 4:動態型別加弱型別不是罪——怎麼 JavaScript 一摔就變成個印度阿三?
  • Day 5:湯姆克魯斯與唐家霸王槍——變數的作用域(Scope) (1)
  • Day 6:湯姆克魯斯與唐家霸王槍——變數的作用域(Scope) (2)
  • Day 7:傳統 var 關鍵字的不足
  • Day 8:var 掰掰 —— ES6 更嚴謹安全的 let 和 const
  • Day 9:圖解變數作用域(Scope)
  • Day 10:程式也懂電梯向上? —— Hoisting
  • Day 11:Strict Mode (嚴謹模式)
  • Day 12:看 Strict Mode 如何施展「還我漂亮拳」(1)
  • Day 13:看 Strict Mode 如何施展「還我漂亮拳」(2)
  • Day 14:來挖挖恐龍骨 —— with 語法
  • Day 15:this 關鍵字 (1)
  • Day 16:this 關鍵字 (2)
  • Day 17:this 關鍵字 (3)
  • Day 18:this 關鍵字 (4)
  • Day 19:函數定義 (Function Definition) 的 100 種寫法
  • Day 20:ES6 的箭頭函數 (Arrow Functions)
  • Day 21:箭頭函數 (Arrow Functions) 的 this 和你想的不一樣 (1)
  • Day 22:箭頭函數 (Arrow Functions) 的 this 和你想的不一樣 (2)
  • Day 23:ES6 物件實字威力加強版 (Enhanced Object Literals)
  • Day 24:函數呼叫 (Function Invocation) 與立即函數 (Self-Invoking Functions)
  • Day 25:不是多了塊魚 —— 立即函數的應用整理
  • Day 26:程式界的哈姆雷特 —— Pass by value, or Pass by reference?
  • Day 27:別管變數 Pass by Whatever,尋找容易理解的銀色子彈 (Silver Bullet)
  • Day 28:閉包 (Closures)
  • Day 29:閉包 (Closures) 進階打怪實戰
  • Day 30:ES10 醞釀中 —— 擁抱 JS の 未來
Powered by GitBook
On this page
  • 嚴謹模式下你不能做的事
  • 1. 不能使用未宣告的變數
  • 2. 不能刪除變數或函數
  • 3. 函數的參數名稱不能重複
  • 4. 不能使用八進制的數字實字 (Octal numeric literals)
  • 5. 不能使用八進制的跳脫字元 (Octal escape characters)
  • 6. 不能對唯讀的物件屬性作寫入 (write to a read-only property of objects)
  • 7. 不能對 get-only 的物件屬性作寫入
  • References

Was this helpful?

Day 12:看 Strict Mode 如何施展「還我漂亮拳」(1)

PreviousDay 11:Strict Mode (嚴謹模式)NextDay 13:看 Strict Mode 如何施展「還我漂亮拳」(2)

Last updated 5 years ago

Was this helpful?

Day11 的文章介紹 JavaScript 中的嚴謹模式 (Strict Mode) 是什麼、如何使用、為什麼要用,並舉了簡單的例子來示範。

嚴謹模式 (Strict Mode) 就像 JavaScript 中的「還我漂亮拳」,能夠讓原本不夠嚴謹、造成混亂的語法,變得更安全、乾淨。

(Source: )

「不允許使用未宣告的變數」只是嚴謹模式最簡單的應用,事實上嚴謹模式發揮的地方非常多。

接下來會用各種例子來檢視嚴謹模式使用前和使用後的效果。

嚴謹模式下你不能做的事

1. 不能使用未宣告的變數

  • 強化變數的控管,快速發現打錯變數名稱的 Bug。

  • 避免不小心產生不必要的 Global 變數 (賦值給尚未宣告的變數,JavaScript 預設行為會產生 Global 變數)。

錯誤類型:ReferenceError: x is not defined

使用前:

x = 3.14;
console.log(x);     // 3.14

使用後:

"use strict";
x = 3.14;           // ReferenceError: x is not defined
console.log(x);

2. 不能刪除變數或函數

  • 不能對變數或函數使用 delete 運算子 (原本對變數或函數作刪除並不會有效果,但也不會拋錯,等於無用的廢 code)

  • 但還是可以對物件屬性或陣列元素使用。

錯誤類型:SyntaxError: Delete of an unqualified identifier in strict mode

使用前:

// variable (沒有作用)
var x = 3.14;
console.log( delete x );                    // false
console.log(x);                             // 3.14

// function via declararion (沒有作用)
function f1(){ console.log('Hi 1'); }
console.log( delete f1 );                   // false
console.log(f1);                            // ƒ f1(){ console.log('Hi 1'); }

// function via expression (沒有作用)
var f2 = function() { console.log('Hi 2'); }
console.log( delete f2 );                   // false
console.log(f2);                            // ƒ () { console.log('Hi 2'); }

// array element
var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log( delete fruits[2] );            // true
console.log(fruits);                        // ["Banana", "Orange", empty, "Mango"]

// object property
var person = {name: 'John', age:18};
console.log( delete person.name );          // true
console.log(person);                        // {age: 18}

使用後:

"use strict";

// variable
var x = 3.14;
console.log( delete x );                    // SyntaxError: Delete of an unqualified identifier in strict mode.

// function via declararion
function f1(){ console.log('Hi 1'); }
console.log( delete f1 );                   // SyntaxError: Delete of an unqualified identifier in strict mode.

// function via expression
var f2 = function() { console.log('Hi 2'); }
console.log( delete f2 );                   // SyntaxError: Delete of an unqualified identifier in strict mode.

// array element
var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log( delete fruits[2] );            // true
console.log(fruits);                        // ["Banana", "Orange", empty, "Mango"]

// object property
var person = {name: 'John', age:18};
console.log( delete person.name );          // true
console.log(person);                        // {age: 18}

3. 函數的參數名稱不能重複

  • 一般模式下,函數的參數名稱如果不慎重複,不會有提醒。

錯誤類型:SyntaxError: Duplicate parameter name not allowed in this context

使用前:

function myFunc(p1, p1){
    console.log(p1);
};

myFunc(10, 20); // 20

使用後:

"use strict";

function myFunc(p1, p1){    // `SyntaxError: Duplicate parameter name not allowed in this context`
    console.log(p1);
};

4. 不能使用八進制的數字實字 (Octal numeric literals)

  • 某些版本的 JavaScript 中,如果數字前頭帶 0,會被直譯為八進制。

  • 例如:var x = 010; 等於十進制的 8。

  • 一般 JavaScript 實作規範中就強烈建議不要對數字開頭帶 0 (但一般模式下仍可被 JavaScript 直譯器接受)。

  • 嚴謹模式會直接對這樣的語法拋錯。

錯誤類型:SyntaxError: Octal literals are not allowed in strict mode

使用前:

var n = 010;
console.log(n);     // 8

使用後:

"use strict";

var n = 010;        // SyntaxError: Octal literals are not allowed in strict mode.
console.log(n);

5. 不能使用八進制的跳脫字元 (Octal escape characters)

  • 例如:var x = "\010";。

註:我個人沒用過這個用法,實際上印出來也只看得到空字串,不知道可以應用在哪。

錯誤類型:SyntaxError: Delete of an unqualified identifier in strict mode.

使用前:

var n = "\010";
console.log(n);     // ""

使用後:

"use strict";

var n = "\010";     // SyntaxError: Octal escape sequences are not allowed in strict mode.
console.log(n);

6. 不能對唯讀的物件屬性作寫入 (write to a read-only property of objects)

  • 在定義物件屬性時,可以設定是否可寫入 (writable)。

  • 一般模式下,如果對 writable:false 的屬性作賦值動作,不會寫入成功,但也不會報錯 (等於廢 code)。

  • 嚴謹模式下會直接拋錯。

錯誤類型:TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'

使用前:

var player = {};
Object.defineProperty(player, "nickname", {value:"OneJar", writable:true});
Object.defineProperty(player, "articleTarget", {value:30, writable:false});
console.log(player);            // {nickname: "OneJar", articleTarget: 30}

player.articleTarget = 100;
console.log(player);            // {nickname: "OneJar", articleTarget: 30}

使用後:

"use strict";

var player = {};
Object.defineProperty(player, "nickname", {value:"OneJar", writable:true});
Object.defineProperty(player, "articleTarget", {value:30, writable:false});
console.log(player);            // {nickname: "OneJar", articleTarget: 30}

player.articleTarget = 100;     // TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'
console.log(player);

7. 不能對 get-only 的物件屬性作寫入

  • 一般模式下,如果對只有 getter 的屬性作賦值動作,不會寫入成功,但也不會報錯 (等於廢 code)。

  • 嚴謹模式下會直接拋錯。

錯誤類型:TypeError: Cannot set property age of #<Object> which has only a getter

使用前:

var person = {get age() {return 18} };
console.log(person);                    // {}
console.log(person.age);                // 18
person.age = 70;
console.log(person.age);                // 18

使用後:

"use strict";

var person = {get age() {return 18} };
console.log(person);                    // {}
console.log(person.age);                // 18
person.age = 70;                        // TypeError: Cannot set property age of #<Object> which has only a getter
console.log(person.age);

References

W3Schools - JavaScript Use Strict
Strict mode - JavaScript | MDN
網路