- Published on
JavaScript 嚴格模式(Strict mode)
- Authors
- Name
- Penghua Chen(PH)
JavaScript 嚴格模式(Strict mode)
簡單介紹
嚴格模式(strict mode) 在ES5被引進,提供開發者能夠在語法更為嚴謹、受限的模式下進行開發,彌補了 JavaScript 的一些重要缺陷。
也提供了更強大的檢查與更高的安全性。
怎麼使用嚴格模式(strict mode)
當設定 'use strict'
或者 "use strict"
,就代表後續的程式碼處於嚴格模式下,但依據設定的位置不同,則嚴格模式的有效範圍也不同:
- 在全域設定的話,代表全部的程式碼都會處於嚴格模式(strict mode);
- 在函式中設定,則嚴格模式(strict mode)的有效範圍則侷限在該函式底下的所有程式碼。
來看看測試例子:
"use strict"
a = 3 ;
function test(){
b = 5;
}
test();
"use strict"
function test(){
b = 5;
}
test();
從上面兩個結果可以得到,==在全域設定嚴格模式(strict mode)==,則所有的程式碼都會在嚴格模式的有效範圍內。
接下再來看看另外一個例子:把 'use strict'
寫在函式內
a = 3;
function test(){
"use strict"
b = 5;
}
test();
從結果可以得知: ==嚴格模式(strict mode)設定在函式內時,則影響的範圍就只有函式內而已==,而全域變數 a
因為不在嚴格模式(strict mode)的有效範圍內,所以會依照原本的方式,被隱性的宣告成全域變數(不會報錯)。
細談嚴格模式(strict mode)
再來要來提提在於嚴格模式(strict mode)下,是什麼做了調整,調整了什麼
- 嚴格模式(strict mode)中,==不允許使用
with
述句==
'use strict'
var a, x, y;
var r = 10;
with (Math) {
a = PI * r * r;
x = r * cos(PI);
y = r * sin(PI / 2);
}
with()
述句會增加程式碼閱讀的困難度,以及變數的查詢,所以在嚴格模式(strict mode)被撇除。
- 嚴格模式(strict mode)中,==所有變數都必須被宣告==,否則會報錯(ReferenceError)。 但在非嚴格模式則視為隱性的宣告全域變數。
a = 3;
function test(){
"use strict"
b = 5;
}
test();
如同前面所提,所有的變數都必須被宣告才可以。
- 嚴格模式(strict mode)中,==不是當作方法的函式==:
this
值為undefined
- 若是使用
call()
,apply()
,bind()
等方法指定this
那麼this
的值就依照其語法設定而決定。 - 但若是使用
call()
,apply()
,bind()
等方法指定this
,但參數為null
、undefined
,則this
為null
、undefined
。不會像非嚴格模式下會自動轉成全域物件。
在非嚴格模式下, this
會指向全域物件,所以可以取得全域變數 age
的值。
var age = 22;
function getAge(){
console.log(this);
console.log(this.age);
}
getAge();
透過如 call()
設定 this
的值,當值為 null
時,則指向全域物件,所以可以獲得和前一個一樣的結果
var age = 22;
function getAge(){
console.log(this);
console.log(this.age);
}
getAge.call(null);
但在嚴格模式下, this
會是 undefined
,所以想取得全域變數 age
的值就會報錯。
'use strict'
var age = 22;
function getAge(){
console.log(this);
console.log(this.age);
}
getAge();
如果透過 call()
設定 this
的值,當值為 null
時 this
值就為 null
,不會指向全域物件。
'use strict'
var age = 22;
function getAge(){
console.log(this);
}
getAge.call(null);
- 嚴格模式(strict mode)中,==對於不可寫入(nonwritable)的物件或不可擴充(nonextensible)的物件嘗試建立新特性會報錯。== 但在非嚴格模式下雖然會失敗,但不會有錯誤訊息。
var obj = {};
Object.defineProperty(obj,"age",{
value: 22,
writable: false,
configurable: false
})
obj.age = 25;
console.log(obj);
但在嚴格模式下,就會提供相關的錯誤訊息了。
'use strict'
var obj = {};
Object.defineProperty(obj,"age",{
value: 22,
writable: false,
configurable: false
})
obj.age = 25;
console.log(obj);
- 物件為唯讀(read only)時,提供相關的錯誤訊息。
- 物件為非擴充性,提供相關的錯誤訊息。
'use strict'
var obj = {};
Object.defineProperty(obj,"age",{
value: 22,
writable: false,
configurable: false
})
Object.seal(obj);
obj.name = "Bill";
console.log(obj);
- 嚴格模式(strict mode)中,==在
eval()
不能宣告變數或者定義函式。== 但在非嚴格模式下可以。
在非嚴格模式下,在 eval()
中宣告變數是被允許的。
eval('var age = 22');
console.log(age);
但在嚴格模式,直接在 eval()
中宣告變數則會報錯。
'use strict'
eval('var age = 22');
console.log(age);
- 嚴格模式(strict mode)中的
arguments
物件:- 是唯讀的
- 對於
arguments.callee
、arguments.caller
存取會報錯
'use strict'
function test(a,b){
console.log(arguments);
console.log(arguments.callee);
}
test(1,2);
- ==在ES6之前== ,嚴格模式(strict mode)中==對於物件特性重複宣告會報錯==,但非嚴格模式中不會發生錯誤。 但==ES6之後並不會有任何錯誤訊息提示==。
- 嚴格模式(strict mode)中, ==
delete
如果不是用於刪除物件特性,就會報錯。== 但在非嚴格模式下則是不會有錯誤訊息,但會回傳false
非嚴格模式下,使用 delete
用於刪除非物件的特性,只會回傳false
var age = 22;
delete age;
但嚴格模式下就會報錯。
'use strict'
var age = 22;
delete age;
- 嚴格模式(strict mode)中, ==函式的參數若是重複命名會報錯。== 但在非嚴格模式下則不會。
非嚴格模式下,下列的程式碼並不會報錯。
function test(a,a){
console.log(a);
}
test(1,2);
但嚴格模式下,參數重複命名就會提示相關錯誤訊息。
'use strict'
function test(a,a){
console.log(a);
}
test(1,2);
- 嚴格模式(strict mode)中,八進位整數字面值(以0開頭,後面不接x)是不被允許的。但在非嚴格模式下有些實作會允許。