《Effective JavaScript 編寫高質量JavaScript程式碼的68個有效方法》

Gyoung阿廣發表於2018-10-26

第1章 讓自己習慣JavaScript

第1條 瞭解你使用的JavaScript版本

確保你使用的任何JavaScript特性對於應用程式將要執行的所有環境都是支援的;

總是在執行嚴格模式檢查的環境中測試嚴格程式碼。

第2條 理解JavaScript的浮點數

事實上,JavaScript中所有的數字都是雙精度浮點數。

位運算將數字視為32位的有符號整數。

浮點數權衡了精度和效能,當我們關心精度時,要小心浮點數的侷限性。一個有效的解決方法是儘可能地採用整數值運算,因為整數在表示時不需要舍入。

第3條 當心隱式的強制轉換

NaN是JavaScript中唯一一個不等於其自身的值,因此,你可以通過檢查一個值是否等於其自身的方式來測試該值是否是NaN。

檢查引數是否為undefined更為嚴格的方式是使用typeof。

物件通過valueOf方法強制轉換為數字,通過toString方法強制轉換為字串。

第4條 原始型別優於封裝物件

除了物件之外,JavaScript有5個原始值型別:布林值、數字、字串、null、undefined。

當對原始值提取屬性和進行方法呼叫時,它表現得就像已經使用了對應的物件型別封裝了該值一樣。

獲取和設定原始型別值的屬性會隱式地建立封裝物件。

第5條 避免對混合型別使用==運算子

null== undefined; 不轉換,總是返回true

當引數型別不同時,==運算子應用了一套難以理解的隱式強制轉換規則。

第6條 瞭解分號插入的侷限

僅在“|”標記之前、一行的結束和程式的結束處推導分號。

僅在緊接著標記不能被解析的時候推導分號。

在return、throw、break、continue、++或—的引數之前絕不能換行。

第7條 視字串為16位的程式碼單元序列

JavaScript字串由16位的程式碼單元組成,而不是由Unicode程式碼點組成。

JavaScript使用兩個程式碼單元表示2^16及以上的Unicode程式碼點,這兩個程式碼單元被稱為代理對。

 

第2章 變數作用域

第8條 儘量少用全域性物件

避免宣告全域性變數,儘量使用區域性變數,避免對全域性物件新增屬性。

使用全域性物件來做平臺特性檢測。

第9條 始終宣告區域性變數

考慮使用lint工具幫助檢查未繫結的變數。

第10條 避免使用with

避免使用with語句。

使用簡短的變數名代替重複訪問的物件。

第11條 熟練掌握閉包

閉包的3個事實:

1.JavaScript允許你引用在當前函式以外定義的變數;

2.即使外部函式已經返回,當前函式仍然可以引用在外部函式所定義的變數;

3.閉包可以更新外部變數的值。

第12條 理解變數宣告提升

在程式碼塊中的變數宣告會被隱式地提升到封閉函式的頂部。

重宣告變數被視為單個變數。

第13條 使用立即呼叫的函式表示式建立區域性作用域

閉包通過引用而不是值捕獲它們的外部變數。

使用立即呼叫的函式表示式來建立區域性作用域。

當心在立即呼叫的函式表示式中包裹程式碼塊可能改變其行為的情形。

第14條 當心命名函式表示式笨拙的作用域

第15條 當心區域性塊函式宣告笨拙的作用域

始終將函式宣告置於程式或被包含的函式的最外層以避免不可移植的行為。

第16條 避免使用eval建立區域性變數

避免使用eval函式建立的變數汙染呼叫者的作用域。

如果eval函式程式碼可能建立全域性變數,將此呼叫封裝到巢狀的函式中以防止作用域汙染。

第17條 間接呼叫eval函式優於直接呼叫

儘可能間接呼叫eval函式,而不要直接呼叫eval函式。

 

第3章 使用函式

第18條 理解函式呼叫、方法呼叫及建構函式呼叫之間的不同

方法呼叫將被查詢方法屬性的物件作為呼叫接收者。

函式呼叫將全域性物件作為其接收者。

建構函式需要通過new運算子呼叫,併產生一個新的物件作為其接收者。

第19條 熟練掌握高階函式

高階函式無非是那些將函式作為引數或返回值的函式。

第20條 使用call方法自定義接收者來呼叫方法

使用call方法可以呼叫在給定物件中不存在的方法。

第21條 使用apply方法通過不同數量的引數呼叫函式

使用apply方法指定一個可計算的引數陣列來呼叫可變引數的函式。

第22條 使用arguments建立可變引數的函式

JavaScript給每個函式都隱式地提供了一個名為arguments的區域性變數。

第23條 永遠不要修改arguments物件

永遠不要修改arguments物件。

使用[].slice.call(arguments)將arguments物件複製到一個真正的陣列中再進行修改。

第24條 使用變數儲存arguments的引用

當引用arguments時當心函式巢狀層級。

繫結一個明確作用域的引用到arguments變數,從而可以在巢狀的函式中引用它。

第25條 使用bind方法提取具有確定接收者的方法

要注意,提取一個方法不會將方法的接收者繫結到該方法的物件上。

使用bind方法建立繫結到適當接收者的函式。

第26條 使用bind方法實現函式柯里化

將函式與其引數的一個子集繫結的技術稱為函式柯里化。

使用bind方法實現函式柯里化,即建立一個固定需求引數子集的委託函式。

傳入null或undefined作為接收者的引數來實現函式柯里化,從而忽略其接收者。

第27條 使用閉包而不是字串來封裝程式碼

當將字串傳遞給eval函式以執行它們的API時,絕不要在字串中包含區域性變數引用。

接受函式呼叫的API優於使用eval函式執行字串的API。

第28條 不要信賴函式物件的toString方法

由於在不同的引擎下呼叫toString方法的結果可能不同,所以絕不要信賴函式原始碼的詳細細節。

toString方法的執行結果並不會暴露儲存在閉包中的區域性變數值。

通常情況下,應該避免使用函式物件的toString方法。

第29條 避免使用非標準的棧檢查屬性

避免使用非標準的arguments.caller和arguments.callee屬性,因為它們不具備良好的移植性。

避免使用非標準的函式物件的caller屬性,因為在包含全部棧資訊方面,它是不可靠的。

 

第4章 物件和原型

第30條 理解prototype、getPrototypeOf和__proto__之間的不同

C.prototype用於建立由new C()建立的物件的原型。

Object.getPrototypeOf(obj)是ES5中用來獲取obj物件的原型物件的標準方法。

obj.__proto__是獲取obj物件的原型物件的非標準方法。

JavaScript中的類本質上是一個建構函式(User)與一個用於在該類(User.prototype)例項間共享方法的原型物件的結合。

第31條 使用Object.getPrototypeOf函式而不要使用__proto__屬性

使用符合標準的Object.getPrototypeOf函式而不要使用非標準的__proto__屬性。

在支援__proto__屬性的非ES5環境中實現Object.getPrototypeOf函式。

第32條 始終不要修改__proto__屬性

避免修改__proto__屬性的最明顯的原因是可移植性問題,因為並不是所有的平臺都支援修改物件原型的特性,所以根本無法編寫可移植的程式碼。

可以使用ES5中的Object.create函式來建立一個具有自定義原型鏈的新物件。

第33條 使建構函式與new操作符無關

通過使用new操作符或Object.create方法在建構函式定義中呼叫自身使得該建構函式與呼叫語法無關。

當一個函式期望使用new操作符呼叫時,清晰地文件化該函式。

第34條 在原型中儲存方法

將方法儲存在原型中,使其可以被所有的例項使用,而不需要儲存方法實現的多個副本,也不需要給每個例項物件增加額外的屬性。

第35條 使用閉包儲存私有資料

JavaScript為資訊隱藏提供了一種非常可靠的機制—閉包。閉包是一種簡樸的資料結構,它們將資料儲存到封閉的變數中而不提供對這些變數的直接訪問。

閉包變數是私有的,只能通過區域性的引用獲取。

將區域性變數作為私有資料從而通過方法實現資訊隱藏。

第36條 只將例項狀態儲存在例項物件中

共享可變資料可能會出問題,因為原型是被其所有的例項共享的。

將可變的例項狀態儲存在例項物件中。

第37條 認識到this變數的隱式繫結問題

this變數的作用域總是由其最近的封閉函式所確定。

使用一個區域性變數(通常命名為self、me或that)使得this繫結對於內部函式是可用的。

第38條 在子類的建構函式中呼叫父類的建構函式

在子類建構函式中顯式地傳入this作為顯式的接收者呼叫父類建構函式。

使用Object.create函式來構造子類的原型物件以避免呼叫父類的建構函式。

第39條 不要重用父類的屬性名

留意父類使用的所有屬性名。

不要在子類中重用父類的屬性名。

第40條 避免繼承標準類

Length的行為只被定義在內部屬性[[class]]的值為“Array”的特殊物件中。

繼承標準類往往會由於一些特殊的內部屬性(如[[class]])而被破壞,所以最好避免繼承以下的標準類:Array、Boolean、Date、Function、Number、RegExp或String。

使用屬性委託優於繼承標準類。

 

未完待續...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章