自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

是時(shí)候開(kāi)始使用JavaScript嚴(yán)格模式了

開(kāi)發(fā) 前端
ECMAScript5將嚴(yán)格模式(strict mode)引入了Javascript中,目的是允許開(kāi)發(fā)人員能夠選擇“更好”的Javascript版本,這個(gè)版本能用不同的方式處理那些普遍而又臭名昭著的錯(cuò)誤。一開(kāi)始的時(shí)候,我對(duì)該模式抱著懷疑的態(tài)度,因?yàn)楫?dāng)時(shí)在只有一款瀏覽器(Firefox)支持嚴(yán)格模式。時(shí)至今日,所有的主流瀏覽器的最新版本——包括IE10與Opera12——都支持嚴(yán)格模式。使用嚴(yán)格模式的時(shí)機(jī)已經(jīng)成熟了。

ECMAScript5將嚴(yán)格模式(strict mode)引入了Javascript中,目的是允許開(kāi)發(fā)人員能夠選擇“更好”的Javascript版本,這個(gè)版本能用不同的方式處理那些普遍而又臭名昭著的錯(cuò)誤。一開(kāi)始的時(shí)候,我對(duì)該模式抱著懷疑的態(tài)度,因?yàn)楫?dāng)時(shí)在只有一款瀏覽器(Firefox)支持嚴(yán)格模式。時(shí)至今日,所有的主流瀏覽器的最新版本——包括IE10與Opera12——都支持嚴(yán)格模式。使用嚴(yán)格模式的時(shí)機(jī)已經(jīng)成熟了。

它帶來(lái)了什么?

嚴(yán)格模式給Javascript的運(yùn)行方式帶來(lái)了許多不同,我將它們分為了兩類:明顯的(obvious),以及微妙的(subtle)。那些微妙的改變是為了解決微妙的問(wèn)題,我不打算在這里對(duì)其進(jìn)行贅述。如果你對(duì)這些細(xì)節(jié)感興趣,請(qǐng)參考Dmitry Soshnikov的精彩文章,《ECMA-262-5 in Detail. Chapter 2. Strict Mode》。我對(duì)介紹明顯的變化更感興趣:它們是你開(kāi)始使用嚴(yán)格模式之前所必須了解的,也可能給你帶來(lái)最多好處。

在開(kāi)始介紹特殊特性之前,你需要記住,嚴(yán)格模式的目標(biāo)之一是允許更快地調(diào)試錯(cuò)誤。幫助開(kāi)發(fā)者調(diào)試的最佳途徑是當(dāng)確定的問(wèn)題發(fā)生時(shí)拋出相應(yīng)的錯(cuò)誤(throw errors when certain patterns occur),而不是悄無(wú)聲息地失敗或者表現(xiàn)出奇怪的行為(這正是如今不在嚴(yán)格模式下的Javascript做的)。嚴(yán)格模式下的代碼拋出更多的錯(cuò)誤信息,這是好事,因?yàn)樗軒椭_(kāi)發(fā)者很快注意到一些必須立即解決的問(wèn)題。

去除with語(yǔ)句(Eliminates with)

首先,嚴(yán)格模式去除了with語(yǔ)句。當(dāng)with語(yǔ)句出現(xiàn)在嚴(yán)格模式中時(shí),它會(huì)被認(rèn)為是非法的Javascript語(yǔ)句并拋出語(yǔ)法錯(cuò)誤。所以,使用嚴(yán)格模式的第一步就是確保你沒(méi)有在使用with。

  1. // 在嚴(yán)格模式中將導(dǎo)致語(yǔ)法錯(cuò)誤  
  2. with (location) {  
  3.     alert(href);  

防止意外的全局變量(Prevents accidental globals)

第二點(diǎn)是,變量在賦值之前必須聲明。在非嚴(yán)格模式下,給一個(gè)未聲明的變量賦值將自動(dòng)生成一個(gè)該名字的全局變量。這是Javascript中最普遍的錯(cuò)誤之一。嚴(yán)格模式中,這樣做將拋出一個(gè)錯(cuò)誤。

  1. // 嚴(yán)格模式中拋出一個(gè)錯(cuò)誤  
  2. (function() {  
  3.     someUndeclaredVar = "foo";  
  4. }()); 

取消this值的強(qiáng)制轉(zhuǎn)換(Eliminates this coercion)

另一個(gè)重要的變化是,當(dāng)this值為null或undefined時(shí),不會(huì)再將其強(qiáng)制轉(zhuǎn)換為全局對(duì)象。也就是說(shuō),this保留了它的原始值,也因此可能會(huì)導(dǎo)致一些依賴于強(qiáng)制轉(zhuǎn)換的代碼發(fā)生錯(cuò)誤。例如:

  1. window.color = "red";  
  2. function sayColor() {  
  3.     // 嚴(yán)格模式下,this不會(huì)指向window  
  4.     alert(this.color);  
  5. }  
  6.  
  7. // 以下兩種情況,在嚴(yán)格模式下都拋出錯(cuò)誤  
  8. sayColor();  
  9. sayColor.call(null); 

根本而言,this值必須賦值,否則將保留undefined值。這意味著調(diào)用構(gòu)造函數(shù)時(shí)若漏掉了new關(guān)鍵字也會(huì)導(dǎo)致錯(cuò)誤:

  1. function Person(name) {  
  2.     this.name = name;  
  3. }  
  4.  
  5. // 嚴(yán)格模式下導(dǎo)致錯(cuò)誤  
  6. var me = Person("Nicholas"); 

在這段代碼里,調(diào)用Person構(gòu)造函數(shù)時(shí)缺少了new關(guān)鍵字,此時(shí)this值為undefined。由于你不能給undefined添加屬性,這段代碼拋出了一個(gè)錯(cuò)誤。在非嚴(yán)格模式下,this會(huì)強(qiáng)制轉(zhuǎn)換為全局對(duì)象,因此name屬性能夠被正確賦值為全局變量。

拒絕重復(fù)(No duplicates)

當(dāng)你做了大量的編碼的時(shí)候,你很容易在對(duì)象中定義了重復(fù)的屬性或者給函數(shù)定義了重復(fù)的參數(shù)名。嚴(yán)格模式下,這兩種情況都會(huì)導(dǎo)致錯(cuò)誤的發(fā)生:

  1. // 嚴(yán)格模式下錯(cuò)誤 - 重復(fù)參數(shù)  
  2. function doSomething(value1, value2, value1) {  
  3.     //code  
  4. }  
  5.  
  6. // 嚴(yán)格模式下錯(cuò)誤 - 重復(fù)屬性  
  7. var object = {  
  8.     foo: "bar",  
  9.     foo: "baz" 
  10. }; 

這兩者都是語(yǔ)法錯(cuò)誤,在代碼執(zhí)行之前將拋出錯(cuò)誤。

更安全的eval()(Safer eval())

eval()沒(méi)有被移除,但它在嚴(yán)格模式下發(fā)生了一些變化。最大的改變是:在eval()語(yǔ)句中聲明的變量以及函數(shù)不會(huì)在包含域中創(chuàng)建。例如:

  1. (function() {  
  2.  
  3.     eval("var x = 10;");  
  4.  
  5.     // 非嚴(yán)格模式下,x為10  
  6.     // 嚴(yán)格模式下,x沒(méi)有聲明,拋出一個(gè)錯(cuò)誤  
  7.     alert(x);  
  8.  
  9. }()); 

任意由eval()創(chuàng)建的變量或函數(shù)仍呆在eval()里。然而,你可以通過(guò)從eval()中返回一個(gè)值的方式實(shí)現(xiàn)值的傳遞:

  1. (function() {  
  2.  
  3.     var result = eval("var x = 10, y = 20; x + y");  
  4.  
  5.     // 嚴(yán)格模式與非嚴(yán)格模式下都能正常工作(得到30)  
  6.     alert(result);  
  7.  
  8. }()); 

不可改變引發(fā)的錯(cuò)誤(Errors for immutables)

ECMAScript 5 同時(shí)引入了修改屬性特征的能力,例如設(shè)置一個(gè)屬性為只讀或者凍結(jié)整個(gè)對(duì)象的結(jié)構(gòu)(freezing an entire object’s structure)。在非嚴(yán)格模式下,試圖修改一個(gè)不可變的屬性時(shí)將悄無(wú)聲息地失敗。你可能在使用一些原生APIs的時(shí)候已經(jīng)遇到這類問(wèn)題。嚴(yán)格模式將保證無(wú)論你在何時(shí)試圖使用一種不被允許的方式修改一個(gè)對(duì)象或?qū)ο蟮膶傩詴r(shí)拋出錯(cuò)誤。

  1. var person = {};  
  2. Object.defineProperty(person, "name" {  
  3.     writable: false,  
  4.     value: "Nicholas" 
  5. });  
  6.  
  7. // 非嚴(yán)格模式下將悄無(wú)聲息地失敗,嚴(yán)格模式則拋出錯(cuò)誤  
  8. person.name = "John"

這個(gè)例子中,name屬性被設(shè)置為只讀。在非嚴(yán)格模式下,對(duì)name的賦值將悄無(wú)聲息地失敗;而在嚴(yán)格模式下,一個(gè)錯(cuò)誤將被拋出。

注:如果你在使用ECMAScript屬性能力(the ECMAScript attribute capabilities),我強(qiáng)烈推薦你開(kāi)啟嚴(yán)格模式。如果你在改變對(duì)象的可變性(mutability of objects),你將遇到一堆錯(cuò)誤,而它們?cè)诜菄?yán)格模式下將被安靜地帶過(guò)。

該如何使用它?

在現(xiàn)代瀏覽器中很容易啟用嚴(yán)格模式,只需添加下面一條語(yǔ)句:

  1. "use strict"

雖然這看起來(lái)只是一個(gè)沒(méi)有賦值給變量的字符串,但它確實(shí)地指示了Javascript引擎切換為嚴(yán)格模式(那些不支持嚴(yán)格模式的瀏覽器只是簡(jiǎn)單地讀取了這個(gè)字符串然后繼續(xù)像平常一樣運(yùn)行)。你可以在全局或函數(shù)中使用它。話雖這么說(shuō),你永遠(yuǎn)不應(yīng)該在全局中使用它。全局地使用這條指示,意味著同個(gè)文件下的所有代碼都在嚴(yán)格模式下運(yùn)行。

  1. // 別這么做  
  2. "use strict";  
  3.  
  4. function doSomething() {  
  5.     // 這將在嚴(yán)格模式下運(yùn)行  
  6. }  
  7.  
  8. function doSomethingElse() {  
  9.     // 這也是  

這看起來(lái)似乎不是個(gè)大問(wèn)題,但在我們這個(gè)不同腳本堆積在一起的世界里(our world of aggressive script concatenation)將導(dǎo)致大麻煩。只要有一份腳本全局地包含這條指令,其它串聯(lián)的腳本也將在嚴(yán)格模式下運(yùn)行(可能引發(fā)一些你從沒(méi)預(yù)想到的錯(cuò)誤)。

因此,最好只在函數(shù)內(nèi)使用嚴(yán)格模式,例如:

  1. function doSomething() {  
  2.     "use strict";  
  3.     // 嚴(yán)格模式下運(yùn)行  
  4. }  
  5.  
  6. function doSomethingElse() {  
  7.     // 非嚴(yán)格模式下運(yùn)行  

如果你想講嚴(yán)格模式應(yīng)用于多個(gè)函數(shù),可以使用如下模式( immediately-invoked function expression (IIFE)):

  1. (function() {  
  2.  
  3.     "use strict";  
  4.  
  5.     function doSomething() {  
  6.         // this runs in strict mode  
  7.     }  
  8.  
  9.     function doSomethingElse() {  
  10.         // so does this  
  11.     }  
  12. }()); 

結(jié)論

我強(qiáng)烈建議每一個(gè)人都開(kāi)始使用嚴(yán)格模式?,F(xiàn)在已經(jīng)有足夠多的瀏覽器支持該模式,它將把你從藏身代碼的錯(cuò)誤中拯救出來(lái)。你需要確保你沒(méi)有全局地包含啟用指令,但可以頻繁地使用IIFEs給任意多的代碼應(yīng)用嚴(yán)格模式。一開(kāi)始,你將碰到從沒(méi)遇過(guò)的錯(cuò)誤——這是很正常的。切換到嚴(yán)格模式后,你需要做足夠多的測(cè)試來(lái)保證你已hold住你的代碼。一定不能只是將“use strict”扔進(jìn)你的代碼然后就假設(shè)不會(huì)有錯(cuò)誤發(fā)生。至少的至少,你該開(kāi)始使用這個(gè)異常有用的語(yǔ)言特性來(lái)寫(xiě)更好的代碼了。

原文:http://zhoujunmiao.com/?p=292

【編輯推薦】

  1. 好用的高質(zhì)量JavaScript庫(kù)一覽
  2. 如何系統(tǒng)地學(xué)習(xí)JavaScript
  3. 2012年3月編程語(yǔ)言排行榜:JavaScript語(yǔ)言的回歸
  4. 性能優(yōu)化:如何更快速加載你的JavaScript頁(yè)面
  5. 從此不再懼怕URI編碼:JavaScript及C# URI編碼詳解
責(zé)任編輯:陳貽新 來(lái)源: zhoujunmiao.com
相關(guān)推薦

2023-10-19 15:25:40

2013-09-22 10:15:01

Spring DataJPA

2019-09-30 10:51:11

Markdown標(biāo)記語(yǔ)言

2017-08-25 14:29:43

機(jī)器學(xué)習(xí)Java

2021-02-14 10:05:54

PowerCLI虛擬化語(yǔ)言

2022-06-09 09:00:00

編程語(yǔ)言后端Dark

2019-02-27 12:00:09

開(kāi)源Org模式Emacs

2022-11-17 07:57:34

2009-09-09 16:46:58

學(xué)習(xí)RubyRuby

2019-12-23 13:20:34

LinuxLumina

2020-03-25 09:53:33

人工智能AI技術(shù)

2011-06-24 17:22:29

Qt Quick QML

2020-04-14 12:12:20

JavaScriptIIFE函數(shù)

2024-05-24 10:01:12

2017-06-27 14:58:21

備份數(shù)據(jù)庫(kù)Oracle

2018-05-09 20:08:09

人工智能深度學(xué)習(xí)Python

2023-01-29 09:15:42

2021-08-11 08:29:25

UbuntuLTS發(fā)布模式

2022-01-24 07:35:39

XLL網(wǎng)絡(luò)攻擊惡意軟件

2023-06-21 08:00:00

微服務(wù)架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)