除了正常運行模式的猛,ECMAscript 5添加了第二種運行模式:"嚴(yán)格模式"(strict mode)。顧名思義,這種模式使得Javascript在更嚴(yán)格的條件下運行徙垫。
為什么提出嚴(yán)格模式
- 消除Javascript語法的一些不合理饺汹、不嚴(yán)謹(jǐn)之處蛔添,減少一些怪異行為;
- 消除代碼運行的一些不安全之處,保證代碼運行的安全兜辞;
- 提高編譯器效率迎瞧,增加運行速度;
- 為未來新版本的Javascript做好鋪墊逸吵。
"嚴(yán)格模式"體現(xiàn)了Javascript更合理凶硅、更安全、更嚴(yán)謹(jǐn)?shù)陌l(fā)展方向扫皱,包括IE 10在內(nèi)的主流瀏覽器足绅,都已經(jīng)支持它捷绑,許多大項目已經(jīng)開始全面擁抱它。
另一方面氢妈,同樣的代碼粹污,在"嚴(yán)格模式"中,可能會有不一樣的運行結(jié)果首量;一些在"正常模式"下可以運行的語句壮吩,在"嚴(yán)格模式"下將不能運行。所以有必要知道里面具體有哪些要求加缘!
首先鸭叙,如何啟用嚴(yán)格模式
使用use strict
這條語句即可
<script>
"use strict";
console.log("這是嚴(yán)格模式。");
</script>
需要注意的是拣宏,嚴(yán)格模式的聲明必須放在腳本的第一行沈贝,否則整個腳本將會以正常模式運行。
除了這種全局的嚴(yán)格模式勋乾,還可以聲明在函數(shù)里面宋下,即局部的嚴(yán)格模式,很多時候局部的嚴(yán)格模式還比較常見市俊。
注意:在函數(shù)里面聲明嚴(yán)格模式杨凑,嚴(yán)格模式只對此函數(shù)內(nèi)的代碼起作用
function strict(){
"use strict";
return "這是嚴(yán)格模式。";
}
function notStrict() {
return "這是正常模式摆昧。";
}
接下來我們一一介紹嚴(yán)格模式都做了哪些規(guī)范:
- 變量必須先聲明后使用
不存在暗示全局變量這種東西了
<script>
"use strict";
a = 1; //報錯
</script>
- 函數(shù)參數(shù)不能有同名屬性撩满,否則報錯
正常模式下,如果函數(shù)有多個重名的參數(shù)绅你,可以用arguments[i]讀取伺帘。嚴(yán)格模式下,這屬于語法錯誤忌锯。
"use strict";
function f(a, a, b) { // 語法錯誤
return ;
}
- 不能使用with
with用于改變代碼塊內(nèi)的的作用域伪嫁,將其設(shè)置為某個對象
function Lakers() {
this.name = "kobe bryant";
this.age = "28";
this.gender = "boy";
}
var people=new Lakers();
with(people){
var str = "姓名: " + name + "<br>"; //直接使用了people對象中的name屬性
str += "年齡:" + age + "<br>";
str += "性別:" + gender;
document.write(str);
}
- 不能使用arguments.callee
callee是arguments的一個屬性,用于返回正在執(zhí)行的函數(shù)本身的引用
function fn(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
- 不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
caller是函數(shù)上面的一個屬性偶垮,保存著調(diào)用當(dāng)前的函數(shù)的函數(shù)引用张咳,如果是全局作用于中調(diào)用當(dāng)前的函數(shù)就返回null
function testFunc() {
'use strict';
console.log(testFunc.caller); //Uncaught TypeError: ...
console.log(testFunc.arguments); //Uncaught TypeError: ...
}
function main() {
testFunc();
}
main();
- 新增一些保留字
ES5本質(zhì)上來講只是一個語言優(yōu)化的過渡,約束了晦澀和不安全的語法似舵,為以后的高級語法鋪平道路脚猾。所以在ES5中新增了一些保留字,嚴(yán)格模式下砚哗,不能使用他們作為變量名或參數(shù)名龙助,包括:
implements, interface, let, package, private, protected, public, static, yield - 禁止this指向全局對象
在嚴(yán)格模式中,this不被允許指向全局蛛芥,如果運行時試圖指向全局提鸟,this將會變?yōu)閡ndefined
'use strict';
var func = function() {
return this;
};
console.log(func() === undefined); //true
- arguments不再追蹤參數(shù)變化
常規(guī)模式下军援,在執(zhí)行函數(shù)時如果我們更改參數(shù)的值,操作結(jié)果會立即映射到arguments對象中称勋,更改arguments對象中的值胸哥,也會立即映射到參數(shù)上!
嚴(yán)格模式約束了這種行為铣缠,將arguments對象與參數(shù)分離烘嘱,更改只會影響自己昆禽,不會對彼此都產(chǎn)生影響
'use strict';
var fn = function(a, b, c) {
a = 10;
console.log(arguments[0]); // 1
arguments[1] = 20;
console.log(b); // 2
};
fn(1, 2, 3);
- eval不會在它的外層作用域引入變量(強制為eval創(chuàng)建新作用域)
常規(guī)模式下蝗蛙,使用eval函數(shù)可能會影響當(dāng)前作用域或全局作用域,給程序的運行結(jié)果帶來不確定性醉鳖,嚴(yán)格模式為JavaScript程序創(chuàng)建了第三種作用域:eval作用域捡硅。eval函數(shù)中的字符串只能在eval作用域內(nèi)運行,所以嚴(yán)格模式下執(zhí)行eval函數(shù)不會對當(dāng)前作用域產(chǎn)生作用
'use strict';
eval("var a = 1;");
console.log(a); //Uncaught ReferenceError: a is not defined
//or
eval("'use strict'; var b = 3;");
console.log(b); //Uncaught ReferenceError: b is not defined
- eval和arguments不能被重新賦值
常規(guī)模式下的JavaScript的隨意性較大盗棵,eval和arguments可以有很多稀奇古怪的用法壮韭,程序雖然可以運行,但這給代碼的可讀性纹因、可維護性也帶來了一些問題喷屋。所以嚴(yán)格模式禁止對eval和arguments做非法操作 - 禁止使用前綴數(shù)字零:0表示八進制數(shù),否則報錯
非嚴(yán)格模式下:
var num1=070; //八進制的56
var num2=079; //無效的八進制數(shù)值瞭恰,解析為79
var num3=08; //無效的八進制數(shù)值屯曹,解析為8
另外,ES6已經(jīng)支持新的語法標(biāo)準(zhǔn)惊畏,八進制以0o來表示恶耽,這樣一來就與16進制的0x形成統(tǒng)一的語法格式:
'use strict';
var a = 017; //Uncaught SyntaxError: ...
var b = 0o17; //ES6 Octal syntax: 8 + 7 = 15
禁止對象屬性重名
非嚴(yán)格模式重復(fù)的屬性,后定義的會覆蓋先定義的颜启。嚴(yán)格模式下會報錯函數(shù)必須聲明在整個腳本或函數(shù)層面
嚴(yán)格模式禁止在語句塊中聲明函數(shù)偷俭,因為當(dāng)調(diào)用該函數(shù)是,會報錯缰盏。
'use strict';
if (true) {
function doSomething() {
console.log('1');
}
} else {
function doSomething() {
console.log('2');
}
}
for (var i = 0; i < 5; i++) {
function doSomething() {
console.log('3');
}
}
doSomething(); //Uncaught ReferenceError: doSomething is not defined
- 不能刪除變量delete prop涌萤,會報錯,只能刪除屬性delete global[prop]
這點視乎非嚴(yán)格模式也是這樣
參考文獻:
ES5規(guī)范之嚴(yán)格模式
嚴(yán)格模式(Strict mode)--w3cschool
附錄C:ECMAScript 的嚴(yán)格模式--w3cschool
ES5 規(guī)范之嚴(yán)格模式詳解
Javascript 嚴(yán)格模式use strict詳解
ES5嚴(yán)格模式
ES5嚴(yán)格模式--騰訊課堂渡一教育
JavaScript中with語句
callee和caller
在JavaScript中定義八進制數(shù)和十六進制數(shù)以及toString方法的一些用法