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

嚴格模式

1、設立嚴格模式的目的

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

2、瀏覽器支持情況

IE10+、Firefox4+、Safari5.1+、Chrome

3、嚴格模式標志

"use strict";

注:老版本的瀏覽器,如不支持嚴格模式,會將其當做一行普通字符串忽略。

4、嚴格模式的使用

  1. 如果'use strict'放在js文件首行,則整個js文件都將以"嚴格模式"運行;(如果該句不在首行,則無效),需要特別注意:多個文件合并成一個文件的情況,此情況下,提供一個方法,每個文件使用匿名函數自執行,將'use strict'放在函數首行;
  2. 將'use strict'放在函數第一行,表示整個函數為'嚴格模式',函數以外在為正常模式;

5、嚴格模式的一些改變

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

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

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

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

<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?
//如果不運行代碼,我們無法知道,因此,這種代碼讓引擎無法進行優化,速度也就會變慢。
}
</pre>

創設eval作用域

正常模式下,JavaScript語言有兩種變量作用域(scope):全局作用域和函數作用域。嚴格模式創設了第三種作用域:eval作用域。

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

this關鍵字指向

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

在嚴格模式下,如果使用call()改變this指針的上下文,如果傳入一個原始值,則會轉換為一個對象;在嚴格模式下,則直接返回原始值;

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

禁止在函數內部遍歷調用棧

<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>

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

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

禁止八進制表示法

  • 正常模式下,整數的第一位為0表示這是八進制數
  • 但是在嚴格模式下這種寫法會報錯
  • ps: parseInt(010) 正常模式下是8,但是嚴格模式不允許使用0開頭的數字,所以此處如果改成 parseInt('010'),結果就不對了
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不再追蹤參數的變化

<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匿名函數自調用,也不能通過arguments.caller來獲取調用函數

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

<pre>
//以下代碼,是MDN實例,但是自測未發現報錯
"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環境下,全局安裝jshint

npm install jshint -g

2、使用方法

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

3、配置文件

  1. 使用-config選項制定配置文件:jshint -config ./xxx ./ 表示檢測當前目錄內所有的js文件,并指定配置文件為當前目錄下的xxx文件。
  2. 使用.jshintrc文件,如果在運行jshint時,沒有-config選項,則會以當前目錄的.jshintrc文件為配置文件,如果當前目錄沒有這個文件,則以其父目錄.jshintrc文件為配置文件,仍沒有的話,則繼續找其父目錄,直至根目錄。
  3. 在nodejs項目的package.json文件的jshintConfig字段中設置配置文件。
  4. 還可以在需檢測的js文件內配置選項/* jshint undef:true,unused:true /* /* global Global */或者 //jshint undef:true,unused:true這兩種方式都可以,如果只把這些注釋寫在某個函數內,則改配置只在函數內起作用。
  5. 有時候我們不希望檢查一些文件(比如一些庫),可以建一個.jshintignore文件,把需要忽略的文件名寫在里面,支持通配符。

4、配置選項

  • asi ----- 如果是真,JSHint會無視沒有加分號的行尾
  • bitwise -----如果為真,JSHint會禁用位運算符 (ps:Javascript允許位運算,但是他卻沒有整型,位運算符要把參與運算的數字從浮點數變為整數,并在運算后再轉換回來。這樣他們的效率就不如在別的語言中那么高)
  • boss -----如果為真,那么JSHint會允許在if,for,while里面編寫賦值語句 (ps:一般來說,我們會在循環、判斷等語句中加入值的比較來做語句的運行條件,有時候會把==錯寫成賦值的=,通常,JSHint會把這個認定為一個錯誤,但是開啟這個選項的化,JSHint就不會檢查判斷條件中的賦值 )
  • curly ----- 如果為真,JSHint會要求你在使用if和while等結構語句時加上{}來明確代碼塊
  • debug ----- 如果為真,JSHint會允許代碼中出現debugger的語句。不過建議你最好在檢測代碼前去掉debug的語句
  • eqeqeq ----- 如果為真,JSHint會看你在代碼中是否都用了===或者是!==,而不是使用==和!=(ps:我們建議你在比較0,”(空字符),undefined,null,false和true的時候使用===和!===)
  • eqnull ----- 如果為真,JSHint會允許使用”== null”作比較(ps:== null 通常用來判斷一個變量是undefined或者是null(當時用==,null和undefined都會轉化為false)
  • evil ----- 如果為真,JSHint會允許使用eval(ps:eval提供了訪問Javascript編譯器的途徑,這有時很有用,但是同時也對你的代碼形成了注入攻擊的危險,并且會對debug造成一些困難,Function構造函數也是另一個‘eval’,另外,當傳入的參數是字符串的時候,setTimeout和setInterval也會類似于eval)
  • forin -----如果為真,那么,JSHint允許在for in 循環里面不出現hasOwnProperty(ps:for in循環一般用來遍歷一個對象的屬性,這其中也包括他繼承自原型鏈的屬性,而hasOwnProperty可以來判斷一個屬性是否是對象本身的屬性而不是繼承得來的)
  • immed -----如果為真,JSHint要求匿名函數的調用如下(ps:(function(){ // }()); 而不是 (function(){ //bla bla })();
  • laxbreak -----如果為真,JSHint則不會檢查換行(ps:Javascript會通過自動補充分號來修正一些錯誤,因此這個選項可以檢查一些潛在的問題)
  • maxerr ----- 設定錯誤的閾值,超過這個閾值jshint不再向下檢查,提示錯誤太多
  • newcap -----如果為真,JSHint會要求每一個構造函數名都要大寫字母開頭
  • noarg -----如果為真,JSHint會禁止arguments.caller和arguments.callee的使用
  • noempty -----如果為真,JSHint會禁止出現空的代碼塊,即沒有語句的代碼塊
  • nomen -----如果為真,JSHint會禁用下劃線的變量名
  • onevar -----如果為真,JSHint期望函數只被var的形式聲明一遍
  • passfail -----如果為真,JSHint會在發現首個錯誤后停止檢查
  • plusplus -----如果為真,JSHint會禁用自增運算和自減運算(ps:++和--可能會帶來一些代碼的閱讀困惑)
  • regexp -----如果為真,JSHint會不允許使用.和[^…]的正則(ps:因為這樣的正則往往會匹配到你不期望的內容,并可能會應用造成一些危害)
  • undef -----如果為真,JSHint會要求所有的非全局變量,在使用前都被聲明(ps:如果你不在一個本地作用域內使用var的方式來聲明變量,Javascript會把它放到全局作用域下面。這樣會很容易引起錯誤)
  • sub -----如果為真,JSHint會允許各種形式的下標來訪問對象(ps:通常,JSHint希望你只是用點運算符來讀取對象的屬性(除非這個屬性名是一個保留字),如果你不希望這樣可以關閉這個選項)
  • strict -----如果為真,JSHint會要求你使用use strict;語法
  • white -----如果為true,JSHint會依據嚴格的空白規范檢查你的代碼
  • Environments -----你的代碼所在的環境

jshint官網

如需轉載,請注明出處!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 一、概述 除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)。...
    Bruce_zhuan閱讀 352評論 0 6
  • 轉自:腳本之家 轉載 時間:2016-09-24我要評論 在 JavaScript 的嚴格模式下,對 JavaSc...
    Michael_林閱讀 422評論 1 1
  • 一、概述 除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)。...
    會飛的豬l閱讀 898評論 0 2
  • 一、概述 除了正常運行模式,ECMAscript 5添加了第二種運行模式:"嚴格模式"(strict mode)。...
    才気莮孒閱讀 201評論 0 1
  • 一到夜晚,總會有一種莫名的孤單和失落。 想起了某個讓我思念的懷抱,心動的感覺,幻想著我就在他懷里,他輕拍著我入睡…...
    陌上薔薇閱讀 182評論 0 0