如何用知名Symbol黑掉JavaScript(5種方法)
他們稱之為知名符號 — 盡管大多數開發者從未使用過它們,甚至從未聽說過它們。
這是一個非常酷的功能,你可以用它來實現這樣的魔法:
你將看到我們如何使用知名 Symbol 構建這些類來實現這一點。
它們全都是關于完全定制內置操作(如for..of)的正常行為。這就像C++和C#中的運算符重載。
它們也都是Symbol類的靜態方法。
1. Symbol.hasInstance
首先我們有Symbol.hasInstance:用于輕松改變instanceof運算符的行為。
通常,instanceof用于檢查一個變量是否是某個類的實例。
就像它應該的那樣;相當標準的東西。
但是使用Symbol.hasInstance,我們可以完全改變instanceof的工作方式:
現在就instanceof而言,一個Person不再是Person了。
如果我們不想完全覆蓋它,而是以一種直觀的方式擴展它呢?
我們不能在 Symbol 內部使用instanceof,因為那會很快導致無限遞歸:
class Person {
static [Symbol.hasInstance](instance) {
return instance instanceof Person; // 無限遞歸!
}
}
相反,我們將對象的特殊constructor屬性與我們自己的進行比較:
如果你剛剛聽說.constructor,這應該解釋一切:
2. Symbol.iterator
我們的下一個黑客技巧是Symbol.iterator,用于完全改變循環如何以及是否在對象上工作。
還記得這個嗎:
我們通過Symbol.iterator實現了這一點:
我們再次看到生成器出現。
每當我們使用for..of時。
這在幕后發生:
因此,通過Symbol.iterator,我們完全改變了for..of對任何List對象的操作:
3. Symbol.toPrimitive
使用Symbol.toPrimitive,我們可以快速從這個:
變成這個:
我們通過覆蓋Symbol.toPrimitive實現了這一點:
現在我們可以在任何使用字符串進行插值和連接的地方使用Person對象:
甚至還有一個hint參數,可以使對象表現得像number、string或其他東西。
4. Symbol.split
天才的知名 Symbol,用于將你的自定義對象轉換為字符串分隔符:
5. Symbol.search
就像Symbol.split一樣,將你的自定義對象轉換為復雜的字符串搜索工具:
最后的思考
從循環到分割再到搜索,知名符號讓我們可以重新定義我們的核心功能,使它們以獨特和令人愉快的方式運行,推動了JavaScript可能性的邊界。