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