Javascript學(xué)習(xí)筆記-Strict Mode

Strict Mode.png

代碼中經(jīng)吃迦看到使用這樣的聲明,卻一直不知道有什么作用济瓢,直到有一天荠割。。旺矾。

1. 歷史

ES5開始使用Directive Prolog蔑鹦,并據(jù)說直到現(xiàn)在也只有'use strict'一個實現(xiàn),至于引入Strict Mode的原因箕宙,總的來還是對JS兼容性對處理嚎朽。
第一,為了處理未來即將廢棄或修改的JS方法柬帕,告訴大家別這樣用了(直接拋出異常了)哟忍。
第二狡门,為了未來兼容的JS實現(xiàn),告訴大家以后的JS這樣做是這個效果锅很。
也就是為了JS更好的發(fā)展其馏,作出的一些JS內(nèi)容上的約束。

2. 聲明位置

作為一個Directive Prolog爆安,只需要使用'use strict'這樣的語法尝偎,就可以聲明為Strict Mode,主要影響范圍會有兩個:

2.1 全局使用

也就是全局都聲明為Strict Mode了鹏控,一般不推薦致扯,因為會對所有的Script引用腳本造成影響,破壞力不可言喻当辐,所以盡量不要這樣使用抖僵。

2.2 方法中使用

這是推薦的方法,只對局部代碼作用缘揪,這樣也不會對其他內(nèi)容產(chǎn)生影響耍群,于是就這樣在方法內(nèi)使用吧。

function f(){
  'use strict'
  // 大括號內(nèi)都有效了找筝,不影響括號外內(nèi)容
}
x = 1;
f()

當(dāng)然這樣也是可以的

(function(){
    'use strict'
})()

3. 使用影響

3.1 對變量的影響

3.1.1 變量聲明

使用不聲明的變量蹈垢,會拋出異常,防止莫名其妙的引入全局變量

  'use strict'
  x = 1 // 愉快的拋出了異常 Uncaught ReferenceError: x is not defined
3.1.2 變量命名

使用關(guān)鍵字/保留字作為變量名袖裕,拋出異常曹抬,常用的關(guān)鍵字:private, package ,protected , interface , implements ,let , static , yield,當(dāng)然不僅僅局限于這些急鳄,可以自行嘗試

function f(){
  'use strict'
  var private = 1 // 很友善的異常信息 Uncaught SyntaxError: Unexpected strict mode reserved word
}
f()
3.1.3 變量賦值

只讀/只有get方法/不可擴展對象屬性賦值谤民,都沒辦法正常賦值,都會拋出異常

function f(){
    'use strict'
    // 只讀屬性
    var obj = {};
    Object.defineProperty(obj, 'x', {value:1 , writable: false, configurable: true});
    obj.x = 2; // Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
    // 只有g(shù)et方法
    var obj = {
        get x() {
           return 1;
        }
     }
     obj.x = 2; // Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
    // 不可擴展對象
    var obj = {};
    Object.preventExtensions(obj);
    obj.x = 2; // Uncaught TypeError: Cannot add property x, object is not extensible
}
f()
3.1.4 方法中形參命名

不能使用相同的形參疾宏,想起來也合理张足,如果兩個參數(shù)名一樣,誰知道指代的哪一個

 (function(){
    'use strict'
    function f(a, a){} // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
  })()
3.1.5 八進制

阻止使用以0開始的八進制表達方式坎藐,可以使用0o的方式來定義八進制數(shù)據(jù)为牍。當(dāng)然避免010這樣的數(shù)據(jù)產(chǎn)生莫名其妙的結(jié)果了(根本不會想到非Strict Mode下 010 === 8

function f() {
    'use strict'
    var x = 010; // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
    var x = 0o10 // 可以這樣用,x === 8
}
3.1.6 禁止給基本類型擴展屬性

我想正常的我們都不會給一個布爾值岩馍,字符串碉咆,數(shù)字增加屬性吧

function f() {
    'use strict'
    false.x = 1; // Uncaught TypeError: Cannot create property 'x' on boolean 'false'
    'str'.x = 1; // Uncaught TypeError: Cannot create property 'x' on string 'str'
}
f()
3.1.7 (超特殊) 對象屬性

對象中含有兩個相同的屬性名,根據(jù)官方文檔時說要報錯的兼雄,結(jié)果似乎被定義為bug了吟逝,目前并不會報錯,只會覆蓋了

function f() {
  'use strict'
  var obj = {x: 1, x: 2} // 據(jù)說會報錯赦肋,結(jié)果現(xiàn)在只是后定義的回覆蓋前面的值
  console.log(obj.x);
}
f();

3.2 function和arguments

3.2.1 Function中this指代

這里其實涉及到另一個知識點this的指代块攒,Javascript中this指代會有一點麻煩励稳,不過這里如果在函數(shù)通常調(diào)用情況下,非Strict Mode返回是window對象囱井,而Strict Mode定義為undefined(原因其實就是方法調(diào)用的時候沒有指向任何對象)

function f() {
  'use strict'
  return this; // undefined 
}
f();
window.f(); // 可以自行嘗試驹尼,有很有意思的結(jié)果
3.2.2 callee, caller, function.arguments

在Strict Mode下使用function.callerfunction.arguments庞呕,arguments.callee新翎,arguments.caller,都會拋出異常住练,我想這么做是為了避免無緣無故就引入了循環(huán)引用導(dǎo)致堆棧溢出地啰。

3.2.3 arguments使用

對于非箭頭函數(shù),方法中可以使用arguments來獲取傳遞參數(shù)讲逛,嚴(yán)格模式下對參數(shù)不會改變aguments對于值的獲取的值亏吝。

  (function(){
      'use strict'
      function f(a){
        a = 2;
        console.log(arguments[0]); // arguments[0] === 1
      }
      f(1);
  })()
3.2.4 (特例)邏輯語句中定義方法

官方似乎是會產(chǎn)生異常的,但是邏輯語句中是不能定義方法的盏混,但是自己嘗試了蔚鸥,似乎都是可以的,也許新版本定義這是可行的许赃?

3.3. eval函數(shù)

3.2.1 作為變量名止喷,方法名,自增數(shù)

和關(guān)鍵字一樣混聊,不能用做以上內(nèi)容弹谁,否則會拋出異常

3.2.2 對全局變量的影響

Strict Mode下不會對全局變量產(chǎn)生影響,聲明的變量只在eval自身的作用域范圍內(nèi)有效

  'use strict'
  var a = 1;
  eval('var a = 2'); // 注意 eval('a = 2')是可以對a產(chǎn)生影響的
  console.log(a); // a === 1;
3.2.3 直接使用和間接使用的區(qū)別

對于間接使用的時候技羔,不受到Strict Mode的限制

'use strict'
eval('var x = 1');
console.log(x); // undefined
// 間接調(diào)用1
('indirect', eval)('var y = 2;'); // indirect
console.log(y); // 2
// 間接調(diào)用2
var ieval = eval;
ieval('var z = 3');
console.log(z);
3.2.4 this.eval和eval的區(qū)別

this又一次立功僵闯,這時候也是可以對全局變量產(chǎn)生影響的

  'use strict'
  var a = 1;
  this.eval('var a = 2');
  console.log(a); // a === 2;

3.4. with函數(shù)

Strict Mode下使用with函數(shù)會直接拋出異常

(function(){
  // Uncaught SyntaxError: Strict mode code may not include a with statement
  'use strict'
  var obj = {x: 1};
  with(obj){
    console.log(x);
  }
})()

3.5 delete

3.5.1 刪除對象屬性

當(dāng)對象屬性設(shè)置為configurable: false的時候,如果刪除對象屬性會拋出異常藤滥,當(dāng)然非Strict Mode也不能刪掉,只是不會拋出異常

(function(){
  'use strict'
  var obj = {};
  Object.defineProperty(obj, 'x', {value: 1, configurable: false});
  delete obj.x; // Uncaught TypeError: Cannot delete property 'x' of #<Object>
})()
3.5.2 刪除變量

變量是不能直接刪除的社裆,會拋出異常拙绊,同樣非Strict Mode下雖然不會拋出異常,但是實際上不能刪除的

(function(){
  // Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
  'use strict'
  var a = 1;
  delete a;
})()
3.5.3 刪除this指代的全局變量

這是可以的泳秀,因為this又一次立功标沪,變成了刪除某個對象的值,所以是可以的

(function(){
  'use strict'
  delete this.a;
  console.log(this);
}).call({a: 1 , b: 2})

4.參考

所有以上內(nèi)容都來自MDN嗜傅,只是對結(jié)構(gòu)按照自己理解做了一下調(diào)整和整合:
MDN strict mode
ECMA-262-5 in detail. Chapter 2. Strict Mode.
MDN Function caller
MDN arguments caller(已淘汰)
MDN arguments callee

5. 練習(xí)

最后來一個練習(xí)吧金句,猜猜結(jié)果:

(function(){
  'use strict'
  var a = b = 1;
  console.log(a);
  console.log(b);
})()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吕嘀,隨后出現(xiàn)的幾起案子违寞,更是在濱河造成了極大的恐慌贞瞒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趁曼,死亡現(xiàn)場離奇詭異军浆,居然都是意外死亡,警方通過查閱死者的電腦和手機挡闰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門乒融,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摄悯,你說我怎么就攤上這事赞季。” “怎么了奢驯?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵碟摆,是天一觀的道長。 經(jīng)常有香客問我叨橱,道長典蜕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任罗洗,我火速辦了婚禮愉舔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伙菜。我一直安慰自己轩缤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布贩绕。 她就那樣靜靜地躺著火的,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淑倾。 梳的紋絲不亂的頭發(fā)上馏鹤,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音娇哆,去河邊找鬼湃累。 笑死,一個胖子當(dāng)著我的面吹牛碍讨,可吹牛的內(nèi)容都是我干的治力。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼勃黍,長吁一口氣:“原來是場噩夢啊……” “哼宵统!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起覆获,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤马澈,失蹤者是張志新(化名)和其女友劉穎瓢省,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箭券,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡净捅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辩块。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛔六。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖废亭,靈堂內(nèi)的尸體忽然破棺而出国章,到底是詐尸還是另有隱情,我是刑警寧澤豆村,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布液兽,位于F島的核電站,受9級特大地震影響掌动,放射性物質(zhì)發(fā)生泄漏四啰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一粗恢、第九天 我趴在偏房一處隱蔽的房頂上張望柑晒。 院中可真熱鬧,春花似錦眷射、人聲如沸匙赞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涌庭。三九已至,卻和暖如春欧宜,著一層夾襖步出監(jiān)牢的瞬間坐榆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工鱼鸠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猛拴,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓蚀狰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親职员。 傳聞我的和親對象是個殘疾皇子麻蹋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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