<article class="hentry">
一、概述
除了正常運行模式扁达,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)正卧。顧名思義,這種模式使得Javascript在更嚴格的條件下運行罩驻。
設(shè)立"嚴格模式"的目的穗酥,主要有以下幾個:
- 消除Javascript語法的一些不合理、不嚴謹之處惠遏,減少一些怪異行為;
- 消除代碼運行的一些不安全之處砾跃,保證代碼運行的安全;
- 提高編譯器效率节吮,增加運行速度抽高;
- 為未來新版本的Javascript做好鋪墊。
"嚴格模式"體現(xiàn)了Javascript更合理透绩、更安全翘骂、更嚴謹?shù)陌l(fā)展方向,包括IE 10在內(nèi)的主流瀏覽器帚豪,都已經(jīng)支持它碳竟,許多大項目已經(jīng)開始全面擁抱它。
另一方面狸臣,同樣的代碼莹桅,在"嚴格模式"中,可能會有不一樣的運行結(jié)果烛亦;一些在"正常模式"下可以運行的語句诈泼,在"嚴格模式"下將不能運行。掌握這些內(nèi)容煤禽,有助于更細致深入地理解Javascript铐达,讓你變成一個更好的程序員。
本文將對"嚴格模式"做詳細介紹檬果。
二瓮孙、進入標志
進入"嚴格模式"的標志,是下面這行語句:
"use strict";
老版本的瀏覽器會把它當作一行普通字符串选脊,加以忽略杭抠。
三、如何調(diào)用
"嚴格模式"有兩種調(diào)用方法知牌,適用于不同的場合。
3.1 針對整個腳本文件
將"use strict"放在腳本文件的第一行斤程,則整個腳本都將以"嚴格模式"運行角寸。如果這行語句不在第一行菩混,則無效,整個腳本以"正常模式"運行扁藕。如果不同模式的代碼文件合并成一個文件沮峡,這一點需要特別注意。
(嚴格地說亿柑,只要前面不是產(chǎn)生實際運行結(jié)果的語句邢疙,"use strict"可以不在第一行,比如直接跟在一個空的分號后面望薄。)
<script>
"use strict";
console.log("這是嚴格模式疟游。");
</script><script>
console.log("這是正常模式。");kly, it's almost 2 years ago now. I can admit it now - I run it on my school's network that has about 50 computers.
</script>
上面的代碼表示痕支,一個網(wǎng)頁中依次有兩段Javascript代碼颁虐。前一個script標簽是嚴格模式,后一個不是卧须。
3.2 針對單個函數(shù)
將"use strict"放在函數(shù)體的第一行另绩,則整個函數(shù)以"嚴格模式"運行。
function strict(){
"use strict";
return "這是嚴格模式花嘶。";
}function notStrict() {
return "這是正常模式椭员。";
}
3.3 腳本文件的變通寫法
因為第一種調(diào)用方法不利于文件合并,所以更好的做法是容劳,借用第二種方法闸度,將整個腳本文件放在一個立即執(zhí)行的匿名函數(shù)之中莺禁。
(function (){
"use strict";
// some code here
})();
四哟冬、語法和行為改變
嚴格模式對Javascript的語法和行為,都做了一些改變可岂。
4.1 全局變量顯式聲明
在正常模式中翰灾,如果一個變量沒有聲明就賦值,默認是全局變量平斩。嚴格模式禁止這種用法绘面,全局變量必須顯式聲明。
"use strict";
v = 1; // 報錯晚凿,v未聲明
for(i = 0; i < 2; i++) { // 報錯塘辅,i未聲明
}
因此扣墩,嚴格模式下,變量都必須先用var命令聲明荆责,然后再使用做院。
4.2 靜態(tài)綁定
Javascript語言的一個特點濒持,就是允許"動態(tài)綁定"柑营,即某些屬性和方法到底屬于哪一個對象,不是在編譯時確定的酒奶,而是在運行時(runtime)確定的奶赔。
嚴格模式對動態(tài)綁定做了一些限制站刑。某些情況下,只允許靜態(tài)綁定摆尝。也就是說结榄,屬性和方法到底歸屬哪個對象囤捻,在編譯階段就確定蝎土。這樣做有利于編譯效率的提高,也使得代碼更容易閱讀挡毅,更少出現(xiàn)意外跪呈。
具體來說取逾,涉及以下幾個方面砾隅。
(1)禁止使用with語句
因為with語句無法在編譯時就確定,屬性到底歸屬哪個對象究反。
"use strict";
var v = 1;
with (o){ // 語法錯誤
v = 2;
}
(2)創(chuàng)設(shè)eval作用域
正常模式下精耐,Javascript語言有兩種變量作用域(scope):全局作用域和函數(shù)作用域晶丘。嚴格模式創(chuàng)設(shè)了第三種作用域:eval作用域浅浮。
正常模式下滚秩,eval語句的作用域,取決于它處于全局作用域本股,還是處于函數(shù)作用域拄显。嚴格模式下,eval語句本身就是一個作用域棘街,不再能夠生成全局變量了遭殉,它所生成的變量只能用于eval內(nèi)部险污。
"use strict";
var x = 2;
console.info(eval("var x = 5; x")); // 5
console.info(x); // 2
4.3 增強的安全措施
(1)禁止this關(guān)鍵字指向全局對象
function f(){
return !this;
}// 返回false蛔糯,因為"this"指向全局對象渤闷,"!this"就是false
function f(){
"use strict";
return !this;
}// 返回true脖镀,因為嚴格模式下蜒灰,this的值為undefined强窖,所以"!this"為true翅溺。
因此,使用構(gòu)造函數(shù)時优幸,如果忘了加new网杆,this不再指向全局對象碳却,而是報錯昼浦。
function f(){
"use strict";
this.a = 1;
};
f();// 報錯,this未定義
(2)禁止在函數(shù)內(nèi)部遍歷調(diào)用棧
function f1(){
"use strict";
f1.caller; // 報錯
f1.arguments; // 報錯
}
f1();
4.4 禁止刪除變量
嚴格模式下無法刪除變量迷帜。只有configurable設(shè)置為true的對象屬性,才能被刪除火诸。
"use strict";
var x;
delete x; // 語法錯誤
var o = Object.create(null, {'x': {
value: 1,
configurable: true
}});delete o.x; // 刪除成功
4.5 顯式報錯
正常模式下置蜀,對一個對象的只讀屬性進行賦值盯荤,不會報錯秋秤,只會默默地失敗灼卢。嚴格模式下鞋真,將報錯涩咖。
"use strict";
var o = {};
Object.defineProperty(o, "v", { value: 1, writable: false });
o.v = 2; // 報錯
嚴格模式下檩互,對一個使用getter方法讀取的屬性進行賦值咨演,會報錯盾似。
"use strict";
var o = {
get v() { return 1; }
};
o.v = 2; // 報錯
嚴格模式下,對禁止擴展的對象添加新屬性溉跃,會報錯撰茎。
"use strict";
var o = {};
Object.preventExtensions(o);
o.v = 1; // 報錯
嚴格模式下,刪除一個不可刪除的屬性炫惩,會報錯他嚷。
"use strict";
delete Object.prototype; // 報錯
4.6 重名錯誤
嚴格模式新增了一些語法錯誤筋蓖。
(1)對象不能有重名的屬性
正常模式下,如果對象有多個重名屬性瓮下,最后賦值的那個屬性會覆蓋前面的值唱捣。嚴格模式下,這屬于語法錯誤拣宰。
"use strict";
var o = {
p: 1,
p: 2
}; // 語法錯誤
(2)函數(shù)不能有重名的參數(shù)
正常模式下,如果函數(shù)有多個重名的參數(shù)晌该,可以用arguments[i]讀取燕耿。嚴格模式下誉帅,這屬于語法錯誤蚜锨。
"use strict";
function f(a, a, b) { // 語法錯誤
return ;
}
4.7 禁止八進制表示法
正常模式下,整數(shù)的第一位如果是0氛悬,表示這是八進制數(shù),比如0100等于十進制的64。嚴格模式禁止這種表示法汛蝙,整數(shù)第一位為0,將報錯西土。
"use strict";
var n = 0100; // 語法錯誤
4.8 arguments對象的限制
arguments是函數(shù)的參數(shù)對象,嚴格模式對它的使用做了限制。
(1)不允許對arguments賦值
"use strict";
arguments++; // 語法錯誤
var obj = { set p(arguments) { } }; // 語法錯誤
try { } catch (arguments) { } // 語法錯誤
function arguments() { } // 語法錯誤
var f = new Function("arguments", "'use strict'; return 17;"); // 語法錯誤
(2)arguments不再追蹤參數(shù)的變化
function f(a) {
a = 2;
return [a, arguments[0]];
}
f(1); // 正常模式為[2,2]
function f(a) {
"use strict";
a = 2;
return [a, arguments[0]];
}
f(1); // 嚴格模式為[2,1]
(3)禁止使用arguments.callee
這意味著,你無法在匿名函數(shù)內(nèi)部調(diào)用自身了觅闽。
"use strict";
var f = function() { return arguments.callee; };
f(); // 報錯
4.9 函數(shù)必須聲明在頂層
將來Javascript的新版本會引入"塊級作用域"摊求。為了與新版本接軌,嚴格模式只允許在全局作用域或函數(shù)作用域的頂層聲明函數(shù)茧痕。也就是說,不允許在非函數(shù)的代碼塊內(nèi)聲明函數(shù)。
"use strict";
if (true) {
function f() { } // 語法錯誤
}
for (var i = 0; i < 5; i++) {
function f2() { } // 語法錯誤
}
4.10 保留字
為了向?qū)鞪avascript的新版本過渡气破,嚴格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。
使用這些詞作為變量名將會報錯。
function package(protected) { // 語法錯誤
"use strict";
var implements; // 語法錯誤
}
此外售碳,ECMAscript第五版本身還規(guī)定了另一些保留字(class, enum, export, extends, import, super),以及各大瀏覽器自行增加的const保留字,也是不能作為變量名的力惯。
五哮缺、參考鏈接
- MDN,
- Dr. Axel Rauschmayer,JavaScript's strict mode: a summary
- Douglas Crockford,
(完)
文檔信息
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)
-
發(fā)表日期:
<abbr class="published" title="2013-01-14T13:42:05+08:00" style="margin: 0px; padding: 0px; list-style-type: none; text-align: left; text-decoration: none; font-weight: normal; font-style: normal; border: none; color: rgb(61, 61, 61);">2013年1月14日</abbr>
-
更多內(nèi)容:
?
博客文集:《前方的路》直撤,《未來世界的幸存者》
-
社交媒體:[image.png
twitter](https://twitter.com/ruanyf)蓖乘,[
image.pngweibo](http://weibo.com/ruanyf)
-
Feed訂閱:
</article>
[圖片上傳中...(image-716522-1512278861101-5)]
相關(guān)文章
-
**2017.09.19:
2017年6月览徒,TC39 委員會正式發(fā)布了《ES2017 標準》纽什。
-
**2017.09.07:
Web 技術(shù)突飛猛進枫慷,但是有一個領(lǐng)域一直無法突破 ---- 游戲探孝。
-
**2017.08.09:
Koa 框架教程**
Node 主要用在開發(fā) Web 應(yīng)用缸濒。這決定了使用 Node栖疑,往往離不開 Web 應(yīng)用框架卿闹。
-
**2017.04.16:
一、什么是內(nèi)存泄漏? 程序的運行需要內(nèi)存。只要程序提出要求,操作系統(tǒng)或者運行時(runtime)就必須供給內(nèi)存奠衔。