Symbol类型详解
Symbol類型詳解
symbol類型通過Symbol函數生成,用于表示獨一無二的值(不使用new關鍵字,直接調用即可創建。例:const s = Symbol("str"))
即使使用相同的字符串來創建Symbol類型的值,這些值也是不同的
symbol值可以調用 toString方法,也可以通過Boolean()轉為 布爾值
a.symbol本身轉為布爾值時為true,取反為false
b.toString調用后會返回Symbol(str)
在ES6中,支持用表達式 (變量)作為屬性名,但表達式必須放在方括號里,由于每個Symbol值都是獨一無二的,就可以用Symbol值作為屬性名,且不會和其他屬性名重復
使用symbol值作為屬性名的屬性訪問只能使用name和 這個symbol值,例:obj[name]
屬性名遍歷
a. symbol類型的屬性并不是私有屬性,但不能通過for in遍歷到,也不能被Object.keys() ,Object。getOwnProperNames(),Json.stringify()獲取到
b. symbol類型屬性名可以通過Object.getOwnPropertySymbol()獲取,但只能獲取到symbol類型的屬性名
c. 使用ES6新提供的Reflect對象的 靜態方法Reflect.ownKeys()可以獲取全部屬性名 ,包括symbol類型和非symbol類型
symbol的靜態方法
a. Symbol.for()
使用Symbol.fro()方法傳入字符串,會先檢查有沒有使用這個字符串調用Symbol.for創建的symbol值,如果有,就返回該值,沒有則進行創建
通過Symbol.for創建的symbol值是全局范圍內的
b. Symbol.keyFor()
調用Symbol.keyfor傳入一個symbol值可以返回該值在全局注冊的鍵名,例
const sym = Symbol.for("aaa"); console.log(Symbol.keyFor(sym)); //會返回aaaES6的11個內置Symbol值
a. Symbol.hasInstance
對象的Symbol.hasInstance指向一個內部方法,如果給一個對象設置了以Symbol.hasInstance為屬性名的方法,當其他對象使用instanceof來判斷是否為該對象實例時,會調用這個方法,傳入的參數為被判斷的這個對象
const obj = {[Symbol.hasInstance](obj2){console.log('obj2');//調用后會打印出{a:111}這個對象} };console.log({a:111} istanceof obj); //{a:111}會作為obj2傳入Symbol.hasInstanceb. Symbol.isConcatSpreadable
該屬性是一個可讀寫的布爾值,默認值為undefined,該屬性控制數組是否能被扁平化,當值為false時,數組不能被扁平化,為true或undefined則可以,例:
let arr1 = [1,2]; console.log([].concat(arr1,[3,4])); //打印結果為[1,2,3,4] console.log(arr1[Symbol.isConcatSpreadable]); //此時該屬性值為默認的undefinedarr1[Symbol.isConcatSpreadable] = true; //把屬性值設置為true console.log([].concat(arr1,[3,4]));//結果同上 console.log(arr1[Symbol.isConcatSpreadable]); //屬性值為truearr1[Symbol.isConcatSpreadable] = false; //再設置為false console.log([].concat(arr1,[3,4])); //此時的結果變成了[Array(2), 3, 4] //展開后是[[1, 2, Symbol(Symbol.isConcatSpreadable): false],3,4] //這里的Symbol(Symbol.isConcatSpreadable): false]不是一個元素,而是一個屬性 console.log(arr1[Symbol.isConcatSpreadable]); //falsec. Symbol.species
定義一個類C,使其繼承自Array,再給類C創建一個實例對象c,c就能繼承Array原型對象上的方法,通過c的map方法衍生一個a對象,分別打印a instanceof C和a instanceof Array,發現結果都為true,說明a既是C的實例對象,也是Array的實例對象
class C extends Array{getName(){return 'aaa';} }; const c = new C(1,2,3); const a = c.map(item=>item+1) console.log(a instanceof Array) console.log(a instanceof C)//兩個結果都為true console.log(a.getName())//aaa如果需要讓a只是Array的實例而不是C的實例,就需要使用Symbol.species,給C定義一個名為Symbol.specied的靜態get存取器方法,并在該方法中返回要構造衍生數組的構造函數
class C extends Array{static get[Symbol.species](){retrun Array;}getName(){return 'aaa';} }; const c = new C(1,2,3); const a = c.map(item=>item+1) console.log(a instanceof Array)//打印true console.log(a instanceof C)//結果為false console.log(a.getName())//a不是C的實例,也不能調用getName方法,會報錯a.getName is not a functiond. Symbol.match,Symbol.replace,Symbol.search,Symbol.split
這四個都指向一個內部方法,當在字符串上調用match,replace,search,和split方法時,會調用這個方法
let obj = {[Symbol.match](str){return str.length} };console.log('aaaaa'.match(obj));//返回值為5e. Symbol.iterator
數組的Symbol.iterator方法指向該數組的默認遍歷器方法,該屬性是可寫的,可以自定義遍歷器方法
f. Symbol.toPrimitive
Symbol.toPrimitive指向一個內部方法,當對象被轉為原始類型是會調用這個方法,這個方法的參數是該對象被轉為的類型
const obj = {[Symbol.toPrimitive](type){console.log(type);} };const a = obj++ //調用方法后會打印numberg. Symbol.toStringTag
對象的Symbol.toStringTag屬性可以是一個字符串也可以是一個存取器get方法,當對象調用toString方法時,會返回[object 返回值]
let obj = {//屬性值為存取器get方法get [Symbol.toStringTag](){return 'aaa';} };let obj2 = {//字符串屬性值[Symbol.toStringTag]:'bbb' }console.log(obj.toString()); //打印[object aaa] console.log(obj2.toString()); //打印[object bbb]h. Symbol.unscopables
對象的該屬性指向一個對象,可以控制這個對象的屬性是否被with環境過濾,
const obj={a:111,b:222,c:333, }obj[Symbol.unscopables]={a:true,b:false }with(obj){// console.log(a);//因為對a設置為了true,所以a屬性會被with環境過濾掉,不能通過with訪問,會報錯console.log(b);//222console.log(c);//333 }console.log(obj[Symbol.unscopables]); //{a: true, b: false}總結
以上是生活随笔為你收集整理的Symbol类型详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js中的symbol详解
- 下一篇: 怎么把证件照背景换成蓝色?一键更换照片背