js中的symbol详解
目錄
Symbol 類型
Symbol() 函數不可以 new
常用的內置符號 Symbol的工廠函數
1.Symbol.asyncIterator
2.Symbol.hasInstance
3.Symbol.isConcatSpreadable
4.Symbol.iterator
5.Symbol.match/replace/search/species/split
Symbol 類型
symbol的實例是唯一的不可變的, 用于確保對象的屬性不重復
使用方式 : 調用 Symbol( 標識 ) 函數 返回一個符號
? ?const a = Symbol('a');const obj = {[a]: 1};console.log(obj); ?// {Symbol(a): 1}Symbol() 函數不可以 new
符號代表唯一的值, 但是我就想用一個符號呢 ?
通過 Symbol.for () 創建一個全局符號
? ?const a = Symbol('a');const b = Symbol.for('b');const b2 = Symbol.for('b');const obj = {[a]: 1,[b]: 2,[b2]: 3};console.log(b === b2); // trueconsole.log(obj); // {Symbol(a): 1, Symbol(b): 3}// key通過覆蓋替換 不必疑惑// b 和 b2 指向同一個符號通過 Symbol.keyFor () 查看全局符號 參數是全局符號 返回符號的描述
如果傳的不是全局符號 返回undefined
如果傳的不是符號 報錯
const b = Symbol.for('b123'); console.log(Symbol.keyFor(b)); // b123常用的內置符號 Symbol的工廠函數
1.Symbol.asyncIterator
此方法返回對象的默認的異步迭代器, 可由 for - await - of 使用
// for await of 會調用對象以[Symbol.asyncIterator]為鍵的函數 該函數返回異步的generator ? class Foo {constructor(n) {this.n = n;this.i = 0;}async *[Symbol.asyncIterator]() {while (this.i < this.n) {yield Promise.resolve(this.i++);}}} ?async function fn() {const p = new Foo(5);for await (const x of p) {console.log(x);}}fn() ?// 0 1 2 3 42.Symbol.hasInstance
該方法判斷一個對象是不是構造函數的實例 , 由 instanceof 使用 , 也就是說 instanceof 檢測數據類型時的原理就是調用了 Symbol.hasInstance
這個屬性被定義在 Function 上 所以函數和類都有 Symbol.hasInstance 方法
? ?class Foo {static [Symbol.hasInstance]() {return false}}const demo = new Foo()console.log(Foo[Symbol.hasInstance](demo)); // falseconsole.log(demo instanceof Foo); // false // 之所以會使false 是因為我重新定義了 [Symbol.hasInstance]() 函數 ? 默認情況下是true3.Symbol.isConcatSpreadable
這個符號作為屬性返回一個布爾值 , 決定拼接數組時是否展開 , 默認為true
? ?let arr = [0];const arr1 = [1];arr1[Symbol.isConcatSpreadable] = true;const arr2 = [2];arr2[Symbol.isConcatSpreadable] = false;arr = arr.concat(arr1, arr2)console.log(arr); // ?[0, 1, Array(1)]4.Symbol.iterator
此方法返回對象默認的迭代器 for of 循環時就會調用對象的 Symbol.iterator函數(返回一個迭代器對象)
? ?class Foo {constructor(n) {this.n = n;this.i = 0;}*[Symbol.iterator]() {while (this.i < this.n) {yield this.i++;}}}async function fn() {const p = new Foo(5);for (const x of p) {console.log(x);}}fn()5.Symbol.match/replace/search/species/split
Symbol允許我們自定義某些函數, 以改變函數原本的行為 .
接下來簡單說明一下
match
match 方法返回字符串匹配正則表達式的結果
即使參數傳入的不是正則表達式 也會調用 new RegExp('xxx') 轉為正則表達式
replace
replace 方法傳入的參數替換字符串匹配正則表達式的結果返回新的字符串
即使參數傳入的不是正則表達式 也會調用 new RegExp('xxx') 轉為正則表達式
search
search 方法傳入的參數為目標字符中出現的位置 ?會調用參數的 Symbol.search 進行求值
即使參數傳入的不是正則表達式 也會調用 new RegExp('xxx') 轉為正則表達式
species
如果你定義一個擴展數組類 那么這個類的實例對象默認是同時指向父類和Array這個構造函數
如果你想只返回Array替換掉他的父類 ?那么可以使用靜態方法?
split
split() 方法以指定字符串分割調用對象, 在此方法調用時會使用以 Symbol.split 為鍵的函數
const str = 'abcd'const res = str.split('') // 等價于 str.split(new RegExp(''))console.log(res); // ['a', 'b', 'c', 'd']// 自定義 splitconst reg = new RegExp('')reg[Symbol.split] = (target) => {return 123}const res1 = str.split(reg)console.log(res1); // 1236.Symbol.toPrimitive
對象轉成字符串會被 String 函數轉化成 '[object Object]'
如果想對對象進行加減運算 , 你可以通過定義 Symbol.toPrimitive 來實現
7.Symbol.toStringTag
對象使用 toString 方法時 會使用 Symbol.toStringTag 的返回值作為數組中的第二項?
我的理解就是 Symbol.toStringTag 方法可以改變(實例對象)的 toString 輸出指定的構造函數
8.Symbol.unscopables
?在 with 語句中 訪問的變量默認都會訪問器參數對象的屬性?
?使用 Symbol.unscopables 可以指定對象哪些屬性不在with環境下生效
總結
以上是生活随笔為你收集整理的js中的symbol详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cocoa初识
- 下一篇: Symbol类型详解