js中的symbol详解
目錄
Symbol 類型
Symbol() 函數(shù)不可以 new
常用的內(nèi)置符號 Symbol的工廠函數(shù)
1.Symbol.asyncIterator
2.Symbol.hasInstance
3.Symbol.isConcatSpreadable
4.Symbol.iterator
5.Symbol.match/replace/search/species/split
Symbol 類型
symbol的實例是唯一的不可變的, 用于確保對象的屬性不重復
使用方式 : 調(diào)用 Symbol( 標識 ) 函數(shù) 返回一個符號
? ?const a = Symbol('a');const obj = {[a]: 1};console.log(obj); ?// {Symbol(a): 1}Symbol() 函數(shù)不可以 new
符號代表唯一的值, 但是我就想用一個符號呢 ?
通過 Symbol.for () 創(chuàng)建一個全局符號
? ?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 () 查看全局符號 參數(shù)是全局符號 返回符號的描述
如果傳的不是全局符號 返回undefined
如果傳的不是符號 報錯
const b = Symbol.for('b123'); console.log(Symbol.keyFor(b)); // b123常用的內(nèi)置符號 Symbol的工廠函數(shù)
1.Symbol.asyncIterator
此方法返回對象的默認的異步迭代器, 可由 for - await - of 使用
// for await of 會調(diào)用對象以[Symbol.asyncIterator]為鍵的函數(shù) 該函數(shù)返回異步的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
該方法判斷一個對象是不是構造函數(shù)的實例 , 由 instanceof 使用 , 也就是說 instanceof 檢測數(shù)據(jù)類型時的原理就是調(diào)用了 Symbol.hasInstance
這個屬性被定義在 Function 上 所以函數(shù)和類都有 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]() 函數(shù) ? 默認情況下是true3.Symbol.isConcatSpreadable
這個符號作為屬性返回一個布爾值 , 決定拼接數(shù)組時是否展開 , 默認為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 循環(huán)時就會調(diào)用對象的 Symbol.iterator函數(shù)(返回一個迭代器對象)
? ?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允許我們自定義某些函數(shù), 以改變函數(shù)原本的行為 .
接下來簡單說明一下
match
match 方法返回字符串匹配正則表達式的結果
即使參數(shù)傳入的不是正則表達式 也會調(diào)用 new RegExp('xxx') 轉(zhuǎn)為正則表達式
replace
replace 方法傳入的參數(shù)替換字符串匹配正則表達式的結果返回新的字符串
即使參數(shù)傳入的不是正則表達式 也會調(diào)用 new RegExp('xxx') 轉(zhuǎn)為正則表達式
search
search 方法傳入的參數(shù)為目標字符中出現(xiàn)的位置 ?會調(diào)用參數(shù)的 Symbol.search 進行求值
即使參數(shù)傳入的不是正則表達式 也會調(diào)用 new RegExp('xxx') 轉(zhuǎn)為正則表達式
species
如果你定義一個擴展數(shù)組類 那么這個類的實例對象默認是同時指向父類和Array這個構造函數(shù)
如果你想只返回Array替換掉他的父類 ?那么可以使用靜態(tài)方法?
split
split() 方法以指定字符串分割調(diào)用對象, 在此方法調(diào)用時會使用以 Symbol.split 為鍵的函數(shù)
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
對象轉(zhuǎn)成字符串會被 String 函數(shù)轉(zhuǎn)化成 '[object Object]'
如果想對對象進行加減運算 , 你可以通過定義 Symbol.toPrimitive 來實現(xiàn)
7.Symbol.toStringTag
對象使用 toString 方法時 會使用 Symbol.toStringTag 的返回值作為數(shù)組中的第二項?
我的理解就是 Symbol.toStringTag 方法可以改變(實例對象)的 toString 輸出指定的構造函數(shù)
8.Symbol.unscopables
?在 with 語句中 訪問的變量默認都會訪問器參數(shù)對象的屬性?
?使用 Symbol.unscopables 可以指定對象哪些屬性不在with環(huán)境下生效
總結
以上是生活随笔為你收集整理的js中的symbol详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cocoa初识
- 下一篇: Symbol类型详解