《JavaScript 權威指南》這本書從第四版開始,一直到第六版,每個版本我都逐字逐句讀過幾遍,然而每一遍下來的感受卻完全不一樣。上上週的星期一,再次翻開了這本犀牛書,這次我是帶著批判精神和研究精神過來的,所以看的時候也寫下了一些感受和筆記,都是些容易被忽略的點,部分內容犀牛書上不一定有提到。
之前都發在 微博 上,稍微整理了一番,放在這裡,方便閱讀。
換個角度理解語句(statemaents)和表達式(expressions):表達式不會改變程式的運作狀態,而語句會。還有一種叫做表達式語句,可以理解為表達式和語句的交集,如({a:1})
、"use strict;"
等,我覺得沒必要死扣,意義不大。
ES3 要求 JS 必須實作 Unicode 2.1 及後續版本,而 ES5 只要求支援 Unicode 3 及後續版本。 Unicode 字符 2005 年超過了十萬字符,至今仍在不斷增修,最新版本是 8.0。
如果你寫JS 程式碼不喜歡帶分號,而又搞不清什麼時候必須加分號,可以這麼做:在以“(“、”[“ 、”/“、”+”、”-“ 開頭的語句前面都加上一個分號,如 ;(a + b).toString()
。
09 是該轉換成9 還是直接報錯?問題,如0x98。原因JS 不能表示所有的實數。
0.3-0.2 != 0.2-0.1,因為在計算的過程中,存在資料的溢出,遺失了精確度。
##系統級、出乎意料的或類似錯誤的值的空缺使用undefined,而程式層級、正常的或意料之中的值的空缺使用null。應該用null。 #eval 是個不好把握的東西,它在ES3 中更像是Function,而在ES5 中更像是一個運算符(嚴格模式下不允許設置別名,否則報錯,且將其作為保留字)。 ES3 中也不被允許為eval 設定別名,然而許多實作卻依然允許,並將其作為全域程式碼來執行,瀏覽器尤其是IE 對它實現相當混亂,沒有什麼規律可循,不過IE 中提供了一個execScript函數,類似全域的eval,這個函數每次執行都會回傳null。引用
這段程式碼執行之後,b.x 依然等於2,原因是{x:2} 這個物件被a 和b 同時引用,delete 指令只刪除了a 對它的引用,b 上的引用依然存在。這種問題有可能造成記憶體洩漏。 Object 擴充功能Object 的 freeze 方法過於嚴格;
/lookupGetter
和對應的 Setter 是很好用的屬性。如圖,你可能還不知道 JavaScript 的 toLocaleString 還可以這麼玩。
this語意this 上下文只存在兩種語義,一種是被當作方法調用,this 指向調用它的物件;一種是作為函數調用,指向Global 物件(嚴格模式下為undefined)。它沒有作用域的限制,如下圖所示,a 由於是作為函數被調用,所以它指向的是 window,故而返回 false。
JavaScript 可以被呼叫執行的均為Function 類型,但是也存在可呼叫的Object,如低版本IE 中的一些宿主物件:document.getElementById、alert 等,在許多瀏覽器中typeof RegExp 同樣是Object。這絕對是一個不標準的實現,在瀏覽器摒棄/修正這些錯誤類型之前應該盡量少依賴它們。
Object.defineProperty 雖然是ES5 的東西,早在IE8 就已經支援了,但支援得併不完善,例如writable、enumerable、configurable 這些配置項設定就無效,IE8 下主要支援getter/setter。
JSON.stringify 接受三個參數,很多人都知道第三個參數可以設定空白字元來美化輸出,但是你可能不知道第二個參數的作用,它為{Array|Function} 類型,如果為Array 則用於過濾key,如果為Function 則可以對value 做處理,如圖所示。
ES6 中新增了一種新的資料類型,Symbol,它是一種原始資料類型(圖一),具備物件的特性(圖二),並且可以指向同一個引用(圖三),能夠作為物件的key 但不可枚舉(圖四),內建的Symbol 會影響程式的執行(圖五),Symbol.iterator 是個舉足輕重的符號,能夠讓元素具備迭代屬性(圖六),花樣很多。
附圖請見://m.sbmmt.com/
偽數組加入Symbol.iterator 的幾個方法:鴨式辨型的iterator 函數、yield 函數和直接使用Array 的遍歷符號。
附圖見://m.sbmmt.com/
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 細節總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!