JavaScript的嚴格模式,和檢測工具

嚴格模式

1化借、設(shè)立嚴格模式的目的

  • 消除JavaScript語法的一些不合理潜慎、不嚴謹之處,減少一些怪異行為蓖康;(會將JavaScript陷阱直接變成明顯錯誤铐炫,靜默失敗)
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全蒜焊;(修正了一些引擎難以優(yōu)化的錯誤)
  • 提高編譯器的效率倒信,增加運行速度;
  • 為未來新版本的JavaScript做好鋪墊泳梆。

2鳖悠、瀏覽器支持情況

IE10+榜掌、Firefox4+、Safari5.1+乘综、Chrome

3憎账、嚴格模式標志

"use strict";

注:老版本的瀏覽器,如不支持嚴格模式卡辰,會將其當(dāng)做一行普通字符串忽略胞皱。

4、嚴格模式的使用

  1. 如果'use strict'放在js文件首行九妈,則整個js文件都將以"嚴格模式"運行反砌;(如果該句不在首行,則無效)允蚣,需要特別注意:多個文件合并成一個文件的情況,此情況下呆贿,提供一個方法嚷兔,每個文件使用匿名函數(shù)自執(zhí)行,將'use strict'放在函數(shù)首行做入;
  2. 將'use strict'放在函數(shù)第一行冒晰,表示整個函數(shù)為'嚴格模式',函數(shù)以外在為正常模式竟块;

5壶运、嚴格模式的一些改變

變量的聲明---嚴格模式下,如果變量沒有聲明就賦值會報錯浪秘;

<pre>
'use strict';
v = 1; //報錯蒋情,v未聲明
for(i = 0; i < 2; i++){} //報錯,i未聲明
</pre>

禁止使用with語句:因為with語句無法再編譯時就確定耸携,屬性到底歸屬哪個對象

首先棵癣,嚴格模式禁用with,with所引起的問題是快內(nèi)的任何名稱可以映射(map)到with傳進來的對象的屬性夺衍,也可以映射到包圍這個塊的作用域內(nèi)的變量(甚至是全局變量)狈谊,這一切都是在運行時決定的;在代碼運行之前是無法得知的沟沙,嚴格模式下河劝,使用with會引起語法錯誤,所以就不會存在with塊內(nèi)的變量在運行時才決定引用到哪里的情況了矛紫。

<pre>
'use strict';
var x = 17;
with(obj){ // 語法錯誤 Uncaught SyntaxError: Strict mode code may not include a with statement
v; //如果沒有開啟嚴格模式赎瞎,with中的這個this指向上面的那個x,還是obj.x颊咬?
//如果不運行代碼煎娇,我們無法知道二庵,因此,這種代碼讓引擎無法進行優(yōu)化缓呛,速度也就會變慢催享。
}
</pre>

創(chuàng)設(shè)eval作用域

正常模式下,JavaScript語言有兩種變量作用域(scope):全局作用域和函數(shù)作用域哟绊。嚴格模式創(chuàng)設(shè)了第三種作用域:eval作用域因妙。

正常模式下,eval語句的作用域票髓,取決于他處于全局作用域攀涵,還是處于函數(shù)作用域。嚴格模式下洽沟,eval語句本身就是一個作用域以故,不再能夠生成全局變量了,他所生成的變量只能用于eval內(nèi)部裆操。
<pre>
'use strcit';
var x = 2;
console.info(eval("var x = 1; x")); // 1
console.info(x); // 2 正常模式下此值為 1
</pre>

this關(guān)鍵字指向

<pre>
function f(){
console.log(this) //window
}
function f(){
'use strict';
console.log(this) //undefined
}
//因此在使用構(gòu)造函數(shù)時怒详,如果沒有實例化new,this不再指向全局對象踪区,而是報錯
</pre>

在嚴格模式下昆烁,如果使用call()改變this指針的上下文,如果傳入一個原始值缎岗,則會轉(zhuǎn)換為一個對象静尼;在嚴格模式下,則直接返回原始值传泊;

<pre>
console.log(function(){
return this; //Number {[[PrimitiveValue]]: 1}
}.call(1))
console.log(function(){
'use strict';
return this; // 1
}.call(1))
</pre>

禁止在函數(shù)內(nèi)部遍歷調(diào)用棧

<pre>
function f(){
'use strict';
f.caller; //報錯鼠渺;
f.arguments; //報錯;
//Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.
}
</pre>

禁止隨意刪除變量

<pre>
'use strict';
var x;
delete x; // 語法報錯
eval('var y; delete y;') //語法報錯
// 正常模式下:delete是無法刪除va聲明出的變量的眷细,不過通過eval聲明的變量系冗,可以被正常刪除
var o = Object.create(null,{'x':{
value : 1,
configurable : true
}});
delete o.x; //刪除成功
</pre>

對一個對象的只讀屬性賦值會報錯

<pre>
// 正常模式下不會報錯
'use strict';
var o = {};
Object.defineProperty(o,'v',{
value : 1,
writable : false
});
o.v = 2; // 報錯;useStrict.html:50 Uncaught TypeError: Cannot assign to read only property "v" of object
</pre>

對一個使用getter方法讀取的屬性賦值會報錯

<pre>
'use strict';
var o = {
get v() {return 1;}
};
o.v = 2; // 報錯薪鹦;
</pre>

對禁止擴展的對象添加新屬性掌敬,會報錯

<pre>
'use strict';
var o = {};
Object.preventExtensions(o);
o.v = 1; // 報錯
</pre>

刪除一個不可刪除的屬性,報錯

<pre>
'use strict';
delete Object.pretotype; //報錯池磁;
</pre>

對象不能有重名的屬性(正常模式是覆蓋奔害,嚴格模式報錯)(此問題測試無結(jié)果,據(jù)說已經(jīng)修正)

函數(shù)不能有重名的參數(shù)(正常模式下可以通過arguments可以讀取地熄,嚴格模式報錯)

禁止八進制表示法

  • 正常模式下华临,整數(shù)的第一位為0表示這是八進制數(shù)
  • 但是在嚴格模式下這種寫法會報錯
  • ps: parseInt(010) 正常模式下是8,但是嚴格模式不允許使用0開頭的數(shù)字端考,所以此處如果改成 parseInt('010'),結(jié)果就不對了
arguments對象的限制

<pre>
'use strict';
arguments++; //報錯
var obj = {set p(arguments){}}; //報錯
try {} catch(arguments){}; //報錯
function arguments(){}; //報錯
var f = new Function('arguments',"'use strcit'; return 1;");//報錯
</pre>

arguments不再追蹤參數(shù)的變化

<pre>
function f(a){
'use strict';
a = 2;
return [a,arguments[0]];
}
f(1); // [2,1] 正常模式下為[2,2]
</pre>

禁止使用arguments.callee,arguments.caller

無法通過arguments.callee匿名函數(shù)自調(diào)用,也不能通過arguments.caller來獲取調(diào)用函數(shù)

函數(shù)必須聲明在頂層(暫時未測試出來結(jié)果)

<pre>
//以下代碼雅潭,是MDN實例揭厚,但是自測未發(fā)現(xiàn)報錯
"use strict";
if (true){
function f() { } // !!! 語法錯誤
f();
}

for (var i = 0; i < 5; i++){
function f2() { } // !!! 語法錯誤
f2();
}

function baz() { // 合法
function eit() { } // 同樣合法
}
</pre>

保留字

嚴格模式新智能了一些保留字,使用這些詞作為變量名將會報錯
implements,interface,let,package,private,protected,public,static,yield,class,enum,export,extends,import,super,const

JavaScript語法檢測工具jshint

1扶供、安裝

在node環(huán)境下筛圆,全局安裝jshint

npm install jshint -g

2、使用方法

  1. 單獨對js文件進行檢測:在該文件目錄下jshint xxx.js
  2. 檢測當(dāng)前目錄及其子目錄所有js文件的語法jshint ./

3椿浓、配置文件

  1. 使用-config選項制定配置文件:jshint -config ./xxx ./ 表示檢測當(dāng)前目錄內(nèi)所有的js文件太援,并指定配置文件為當(dāng)前目錄下的xxx文件。
  2. 使用.jshintrc文件扳碍,如果在運行jshint時提岔,沒有-config選項,則會以當(dāng)前目錄的.jshintrc文件為配置文件笋敞,如果當(dāng)前目錄沒有這個文件碱蒙,則以其父目錄.jshintrc文件為配置文件,仍沒有的話夯巷,則繼續(xù)找其父目錄赛惩,直至根目錄。
  3. 在nodejs項目的package.json文件的jshintConfig字段中設(shè)置配置文件鞭莽。
  4. 還可以在需檢測的js文件內(nèi)配置選項/* jshint undef:true,unused:true /* /* global Global */或者 //jshint undef:true,unused:true這兩種方式都可以坊秸,如果只把這些注釋寫在某個函數(shù)內(nèi)麸祷,則改配置只在函數(shù)內(nèi)起作用澎怒。
  5. 有時候我們不希望檢查一些文件(比如一些庫),可以建一個.jshintignore文件阶牍,把需要忽略的文件名寫在里面喷面,支持通配符。

4走孽、配置選項

  • asi ----- 如果是真惧辈,JSHint會無視沒有加分號的行尾
  • bitwise -----如果為真,JSHint會禁用位運算符 (ps:Javascript允許位運算磕瓷,但是他卻沒有整型盒齿,位運算符要把參與運算的數(shù)字從浮點數(shù)變?yōu)檎麛?shù),并在運算后再轉(zhuǎn)換回來困食。這樣他們的效率就不如在別的語言中那么高)
  • boss -----如果為真边翁,那么JSHint會允許在if,for硕盹,while里面編寫賦值語句 (ps:一般來說符匾,我們會在循環(huán)、判斷等語句中加入值的比較來做語句的運行條件瘩例,有時候會把==錯寫成賦值的=啊胶,通常甸各,JSHint會把這個認定為一個錯誤,但是開啟這個選項的化焰坪,JSHint就不會檢查判斷條件中的賦值 )
  • curly ----- 如果為真趣倾,JSHint會要求你在使用if和while等結(jié)構(gòu)語句時加上{}來明確代碼塊
  • debug ----- 如果為真,JSHint會允許代碼中出現(xiàn)debugger的語句琳彩。不過建議你最好在檢測代碼前去掉debug的語句
  • eqeqeq ----- 如果為真誊酌,JSHint會看你在代碼中是否都用了===或者是!==,而不是使用==和!=(ps:我們建議你在比較0露乏,”(空字符)碧浊,undefined,null瘟仿,false和true的時候使用===和!===)
  • eqnull ----- 如果為真箱锐,JSHint會允許使用”== null”作比較(ps:== null 通常用來判斷一個變量是undefined或者是null(當(dāng)時用==,null和undefined都會轉(zhuǎn)化為false)
  • evil ----- 如果為真劳较,JSHint會允許使用eval(ps:eval提供了訪問Javascript編譯器的途徑驹止,這有時很有用,但是同時也對你的代碼形成了注入攻擊的危險观蜗,并且會對debug造成一些困難臊恋,F(xiàn)unction構(gòu)造函數(shù)也是另一個‘eval’,另外墓捻,當(dāng)傳入的參數(shù)是字符串的時候抖仅,setTimeout和setInterval也會類似于eval)
  • forin -----如果為真,那么砖第,JSHint允許在for in 循環(huán)里面不出現(xiàn)hasOwnProperty(ps:for in循環(huán)一般用來遍歷一個對象的屬性撤卢,這其中也包括他繼承自原型鏈的屬性,而hasOwnProperty可以來判斷一個屬性是否是對象本身的屬性而不是繼承得來的)
  • immed -----如果為真梧兼,JSHint要求匿名函數(shù)的調(diào)用如下(ps:(function(){ // }()); 而不是 (function(){ //bla bla })();
  • laxbreak -----如果為真放吩,JSHint則不會檢查換行(ps:Javascript會通過自動補充分號來修正一些錯誤,因此這個選項可以檢查一些潛在的問題)
  • maxerr ----- 設(shè)定錯誤的閾值羽杰,超過這個閾值jshint不再向下檢查渡紫,提示錯誤太多
  • newcap -----如果為真,JSHint會要求每一個構(gòu)造函數(shù)名都要大寫字母開頭
  • noarg -----如果為真考赛,JSHint會禁止arguments.caller和arguments.callee的使用
  • noempty -----如果為真惕澎,JSHint會禁止出現(xiàn)空的代碼塊,即沒有語句的代碼塊
  • nomen -----如果為真欲虚,JSHint會禁用下劃線的變量名
  • onevar -----如果為真集灌,JSHint期望函數(shù)只被var的形式聲明一遍
  • passfail -----如果為真,JSHint會在發(fā)現(xiàn)首個錯誤后停止檢查
  • plusplus -----如果為真,JSHint會禁用自增運算和自減運算(ps:++和--可能會帶來一些代碼的閱讀困惑)
  • regexp -----如果為真欣喧,JSHint會不允許使用.和[^…]的正則(ps:因為這樣的正則往往會匹配到你不期望的內(nèi)容腌零,并可能會應(yīng)用造成一些危害)
  • undef -----如果為真,JSHint會要求所有的非全局變量唆阿,在使用前都被聲明(ps:如果你不在一個本地作用域內(nèi)使用var的方式來聲明變量益涧,Javascript會把它放到全局作用域下面。這樣會很容易引起錯誤)
  • sub -----如果為真驯鳖,JSHint會允許各種形式的下標來訪問對象(ps:通常闲询,JSHint希望你只是用點運算符來讀取對象的屬性(除非這個屬性名是一個保留字),如果你不希望這樣可以關(guān)閉這個選項)
  • strict -----如果為真浅辙,JSHint會要求你使用use strict;語法
  • white -----如果為true扭弧,JSHint會依據(jù)嚴格的空白規(guī)范檢查你的代碼
  • Environments -----你的代碼所在的環(huán)境

jshint官網(wǎng)

如需轉(zhuǎn)載,請注明出處记舆!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸽捻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泽腮,更是在濱河造成了極大的恐慌御蒲,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诊赊,死亡現(xiàn)場離奇詭異厚满,居然都是意外死亡,警方通過查閱死者的電腦和手機碧磅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門碘箍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人续崖,你說我怎么就攤上這事敲街⊥鸥悖” “怎么了严望?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逻恐。 經(jīng)常有香客問我像吻,道長,這世上最難降的妖魔是什么复隆? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任拨匆,我火速辦了婚禮,結(jié)果婚禮上挽拂,老公的妹妹穿的比我還像新娘惭每。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布台腥。 她就那樣靜靜地躺著宏赘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黎侈。 梳的紋絲不亂的頭發(fā)上察署,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音峻汉,去河邊找鬼贴汪。 笑死,一個胖子當(dāng)著我的面吹牛休吠,可吹牛的內(nèi)容都是我干的扳埂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瘤礁,長吁一口氣:“原來是場噩夢啊……” “哼聂喇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔚携,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤希太,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后酝蜒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體誊辉,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年亡脑,在試婚紗的時候發(fā)現(xiàn)自己被綠了堕澄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡霉咨,死狀恐怖蛙紫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情途戒,我是刑警寧澤坑傅,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站喷斋,受9級特大地震影響唁毒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜星爪,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一浆西、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顽腾,春花似錦近零、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猪瞬。三九已至,卻和暖如春入篮,著一層夾襖步出監(jiān)牢的瞬間陈瘦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工潮售, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留痊项,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓酥诽,卻偏偏與公主長得像鞍泉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肮帐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一咖驮、概述 除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)训枢。...
    Bruce_zhuan閱讀 346評論 0 6
  • 轉(zhuǎn)自:腳本之家 轉(zhuǎn)載 時間:2016-09-24我要評論 在 JavaScript 的嚴格模式下托修,對 JavaSc...
    Michael_林閱讀 416評論 1 1
  • 一、概述 除了正常運行模式恒界,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)睦刃。...
    會飛的豬l閱讀 881評論 0 2
  • 一、概述 除了正常運行模式十酣,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)涩拙。...
    才気莮孒閱讀 193評論 0 1
  • 一到夜晚,總會有一種莫名的孤單和失落耸采。 想起了某個讓我思念的懷抱兴泥,心動的感覺,幻想著我就在他懷里虾宇,他輕拍著我入睡…...
    陌上薔薇閱讀 179評論 0 0