那些容易被忽視的 JavaScript 細節總結
《JavaScript 權威指南》這本書從第四版開始,一直到第六版,每個版本我都逐字逐句讀過幾遍,然而每一遍下來的感受卻完全不一樣。上上週的週一,再次翻開了這本犀牛書,這一次我是帶著批判精神和研究精神過來的,所以看的時候也寫下了一些感受和筆記,都是些容易被忽略的點,部分內容犀牛書上不一定有提到。
之前都發在 微博 上,稍微整理了一番,放在這裡,方便閱讀。
語句/表示式
換個角度理解語句(statemaents)和表示式(expressions):表示式不會改變程式的執行狀態,而語句會。還有一種叫做表示式語句,可以理解為表示式和語句的交集,如({a:1})
、"use strict;"
等,我覺得沒必要死扣,意義不大。
字符集
ES3 要求 JS 必須實現 Unicode 2.1 及後續版本,而 ES5 只要求支援 Unicode 3 及後續版本。Unicode 字元 2005 年超過了十萬字元,至今仍在不斷增修,最新版本是 8.0。
分號
如果你寫 JS 程式碼不喜歡帶分號,而又搞不清什麼時候必須加分號,可以這麼做:在以 “(“、”[“ 、”/“、”+”、”-“ 開頭的語句前面都加上一個分號,如 ;(a + b).toString()
。
進位制
ES5 嚴格模式中禁止使用八進位制。目前各種引擎對 JS 的實現是存在差異的,部分支援八進位制,部分不支援。八進位制被禁止的原因:String 和 Number 之間經常被相互轉換,而以0
開頭的八進位制資料特別容易讓人迷惑,也容易讓機器迷惑,比如 09
是該被轉換成 9 還是直接報錯?十六進位制不存在這個問題,如 0x98。更多資訊參閱 這裡。
精度
JS 採用 IEEE-754 浮點數表示法,這是一種二進位制表示法,由於精度原因 JS 不能表示所有的實數。它能展示的浮點數個數是有限的,比如它不能準確地表示三分之一的數值字面量。這也導致了它在浮點數的計算上存在誤差,如 0.3-0.2 != 0.2-0.1
,因為在計算的過程中,存在資料的溢位,丟失了精度。
null/undefined
系統級、出乎意料的或者類似錯誤的值的空缺使用 undefined,而程式級、正常的或意料之中的值的空缺使用 null。平時程式設計給變數賦值時,不要使用 undefined 而應該用 null。值得注意的是 ES3 中的 undefined 是可以被重新賦值的,ES5 修復了這個 bug。通常我們使用 void 0 來還原/代替 undefined 的值。
eval
eval 是個不好把握的東西,它在 ES3 中更像是 Function,而在 ES5 中更像是一個運算子(嚴格模式下不允許設定別名,否則報錯,且將其作為保留字)。實際上 ES3 中也不允許給 eval 設定別名,然而很多實現卻依然允許,並將其作為全域性程式碼來執行,瀏覽器尤其是 IE 對它實現相當混亂,沒有什麼規律可循,不過 IE 中提供了一個 execScript 函式,類似全域性的 eval,這個函式每次執行都會返回 null。
需要使用 eval 的場景並不多,儘量少用,一般需求使用 new Function 就能滿足。
引用
刪除屬性存在的坑:a = {n: {x: 2}}, b = a.n; delete a.n;
這段程式碼執行之後,b.x 依然等於 2,原因是 {x:2} 這個物件被 a 和 b 同時引用,delete 指令只刪除了 a 對它的引用,b 上的引用依然存在。這種問題有可能造成記憶體洩漏。
Object 擴充套件
Object 的 freeze 方法過於嚴格;defineGetter/lookupGetter 和對應的 Setter 是很好用的屬性。
toLocalString
如圖,你可能還不知道 JavaScript 的 toLocaleString 還可以這麼玩。
this語義
this 上下文只存在兩種語義,一種是被當作方法呼叫,this 指向呼叫它的物件;一種是作為函式呼叫,指向 Global 物件(嚴格模式下為 undefined)。它沒有作用域的限制,如下圖所示,a 由於是作為函式被呼叫,所以它指向的是 window,故而返回 false。
型別
JavaScript 可以被呼叫執行的均為 Function 型別,但是也存在可呼叫的 Object,如低版本 IE 中的一些宿主物件:document.getElementById、alert 等,在很多瀏覽器中 typeof RegExp 同樣是 Object。這絕對是一個不標準的實現,在瀏覽器摒棄/修正這些錯誤型別之前應該儘量少依賴它們。
IE8 getter/setter
Object.defineProperty 雖然是 ES5 的東西,早在 IE8 就已經支援了,但支援得並不完善,比如 writable、enumerable、configurable 這些配置項設定就無效,IE8 下主要支援 getter/setter。
JSON.stringify
JSON.stringify 接受三個引數,很多人都知道第三個引數可以設定空白字元來美化輸出,但是你可能不知道第二個引數的作用,它為 {Array|Function} 型別,如果為 Array 則用於過濾 key,如果為 Function 則可以對 value 做處理,如圖所示。
Symbol
ES6 中新增了一種新的資料型別,Symbol,它是一種原始資料型別(圖一),具備物件的特性(圖二),並可以指向同一個引用(圖三),能夠作為物件的 key 但不可列舉(圖四),內建的 Symbol 會影響程式的執行(圖五),Symbol.iterator 是個舉足輕重的符號,能夠讓元素具備迭代屬性(圖六),花樣很多。
附圖見:http://weibo.com/1812166904/DqMwR8O6z
偽陣列新增 Symbol.iterator 的幾個辦法:鴨式辨型的 iterator 函式、yield 函式和直接使用 Array 的遍歷符號。
附圖見:http://weibo.com/1812166904/DqMBYebPw
Set/WeakSet
Set/WeakSet 這種資料結構,不能說沒用,但確實也沒啥大用,前者就是個不允許出現重複成員的陣列,順便還帶了點 ES6 的特性,後者雖說可以一定程度上防止記憶體洩漏,但是也容易出錯,比如某個引用已經被垃圾回收了,再去使用它可能就返回 null。它們都是 ES6 的配套產物。而 Map/WeakMap 倒是兩個非常不錯的設計,常規的 Object 結構都為 String-Val 鍵值對,而它擴充套件為 AllType-Val,任意型別都可以作為它的 Key,無論是服務端程式設計還是客戶端程式設計,這個屬性都帶來了極大的便利性。
正則
理解正則零寬的含義:正則中所謂的零寬斷言,類似於錨點字元,它們匹配指定的位置而不會匹配內容,如 ^ 匹配開頭,$ 匹配結尾,\b 匹配單詞邊界;(?=p) 匹配「接下來的字元與 p 匹配」的位置,(?!p) 匹配「接下來的字元不與 p 匹配」的位置。\b 字元匹配單詞邊界,實際上就是匹配 \w 與 \W 之間的位置(\w 匹配 [a-zA-Z0-9])。很少會有人用到 \B,它匹配的是非單詞邊界位置,簡單理解就是 \w & \w 之間位置或者 \W & \W 之間位置。
持續學習和分享…
內容都是片段化的分享,比較多,也比較雜,就沒有全部列舉出來,感興趣的同學可以 follow 我的 微博,我的想法和筆記都會在上面同步。
感受
在這之前犀牛書已經翻閱了差不多六七遍,很多內容都已經深深地刻在了腦海裡,但時間久了也會忘記些,時而鞏固複習下,畢竟是前端最基礎部分。
帶著問題去看書,收穫是完全不一樣的。犀牛書不難啃,難的是你對這些知識點的理解深度。
相關文章
- 網頁設計中那些不容忽視的細節網頁
- 那些被忽略的 JavaScript 陣列方法細節JavaScript陣列
- 專案開發中容易被忽視的部分
- 容易忽視的細節:Log4j 配置導致的零點介面嚴重超時
- 細節決定成敗!APP設計不容忽視的20個細節APP
- 不要忽視Web程式設計中的小細節Web程式設計
- 細節總結
- Vue中那些容易被忽略的~Vue
- spring rest 容易被忽視的後端服務 chunked 效能問題SpringREST後端
- Web開發和設計上容易被忽視的8個錯誤Web
- Python 元組列表排序:初學者可能忽視的細節Python排序
- 淺談SEO技巧之一:SEO容易忽視的5種連結
- 【JavaScript高階進階】JavaScript變數/函式提升的細節總結JavaScript變數函式
- 細節決定成敗,不容忽視的10道Node面試題面試題
- 從應用開發到營收 10個不能忽視的細節營收
- 爬蟲細節總結爬蟲
- Pandas切片操作:很容易忽視的SettingWithCopyWarning
- Oracle中最容易被忽略的那些實用特性Oracle
- 被忽視的開發安全問題
- 建立 UIWindow 被忽視的一個坑UI
- Oracle SQL細節總結(一)OracleSQL
- 看FCOS時的小細節總結
- 編寫約玩原始碼不能忽視的細節,拒絕Bug找上門原始碼
- 容易忽視的十大SQL最佳化方案!SQL
- 一點被忽視的模型使用方法模型
- Oracle細節及難點總結Oracle
- 解謎遊戲不可忽視的細節——《COCOON》的隱性引導設計遊戲
- 杜絕安全隱患 容易忽視的Oracle安全問題(轉)Oracle
- 忽視細節導致簡單問題的複雜化 關於PUPBLD.SQLSQL
- 那些害死程式設計師的細節程式設計師
- Beego 中容易被我們忽視的問題之 Memory 快取篇Go快取
- 使用者容易忽視的網路安全錯誤操作盤點
- 遊戲出海想賺得盆滿缽滿又所求無門?這些容易被忽視的坑點要避免遊戲
- 提高javascript效能的小細節JavaScript
- Vue、Javascript小細節VueJavaScript
- 帶你理解 JS 容易出錯的坑和細節JS
- oDesk個人資料:容易忽視的6個方面及相應對策
- 可能被忽略的"按鈕元件"細節元件