
說(shuō)到Symbol就先來(lái)說(shuō)下 js中的基礎(chǔ)數(shù)據(jù)類(lèi)型 string、number、boolean、null、undefined,Symbol就是js中的第六種基礎(chǔ)數(shù)據(jù)類(lèi)型
用一句話來(lái)描述Symbol,那就是獨(dú)一無(wú)二!
Symbol的使用
基本使用
consts1 = Symbol('song');
consts2 = Symbol('song');
// Symbol中的標(biāo)識(shí)一般放number、string
console.log(s1 === s2);// Symbol聲明的變量不相等
Symbol作為key
consts1 = Symbol('song');
letobj = {
[s1]:'song',// es6語(yǔ)法[] 可以將symbol的值作為屬性
age:18
}
for(letkeyinobj){// for循環(huán)無(wú)法遍歷symbol屬性
console.log(obj[key])
}
// Reflect.ownKeys方法可以拿到所有的key屬性
Reflect.ownKeys(obj).forEach(key=>{
console.log(obj[key]);
})
Symbol.for
我們上面說(shuō)symbol是獨(dú)一無(wú)二的,但是有的時(shí)候我希望可以復(fù)用聲明過(guò)的symbol,可以使用for語(yǔ)法,如果symbol不存在則聲明,如果存在則將創(chuàng)建過(guò)的symbol返回回來(lái)!
consts1 = Symbol.for('song');
consts2 = Symbol.for('song');
console.log(s1 === s2);
console.log(Symbol.keyFor(s2));// 可以通過(guò)keyFor 獲取symbok的key
Symbol元編程
元編程:可以去對(duì)原生js的操作進(jìn)行修改,說(shuō)白了就是可以更改原生js的行為
ES6提供了11個(gè)內(nèi)置的Symbol值
1.Symbol.hasInstance
重寫(xiě)instanceof默認(rèn)行為
constinstance = {
[Symbol.hasInstance](value){
return'a'invalue
}
}
// 當(dāng)調(diào)用 instanceof 方法,會(huì)默認(rèn)調(diào)用instance上的hasInstance方法
console.log({a:1}instanceofinstance)
2.Symbol.isConcatSpreadable
重寫(xiě)數(shù)組的展開(kāi)行為
constarr = [1,2,3];
arr[Symbol.isConcatSpreadable] =false;
console.log(arr.concat([1,2,3]));
3.Symbol.match / split / search / replace
重寫(xiě)字符串的match,split,search方法
constobj = {
[Symbol.match](value){
returnvalue.length ===3
}
}
console.log('abc'.match(obj));
4.Symbol.species
創(chuàng)建衍生對(duì)象時(shí),指定構(gòu)造函數(shù)
classMyArray extendsArray{
constructor(...args){
super(...args);
}
static get [Symbol.species](){
returnArray;// 創(chuàng)建衍生對(duì)象會(huì)用Array作為構(gòu)造函數(shù)
}
}
constarr =newMyArray(1,2,3);
constnewArr = arr.map(item=>item*2);
console.log(newArrinstanceofMyArray);// 默認(rèn)衍生對(duì)象也是MyArray的實(shí)例
5.Symbol.toPrimitive
重寫(xiě)數(shù)據(jù)類(lèi)型轉(zhuǎn)化
constobj = {
[Symbol.toPrimitive](type){// type number string default
return123;
}
}
console.log(obj*123);
6.Symbol.toStringTag
重寫(xiě)toString方法
constobj = {
[Symbol.toStringTag]:"xxx"
};
console.log(Object.prototype.toString.call(obj));// [object xxx]
7.Symbol.unscopables
重寫(xiě)哪些屬性被with所排除
console.log(Array.prototype[Symbol.unscopables]);// 哪些方法不能再with中使用
with(Array.prototype){// 直接調(diào)用數(shù)組原型上的方法
forEach.call([1,2,3],element => {
console.log(element)
});
}
classMyClass {
eat() {}
get [Symbol.unscopables]() {
return{ eat:true};// 不能在with下使用
}
}
with(MyClass.prototype) {
console.log(eat);
}
還差最后一個(gè)Symbol.iterator,留個(gè)小尾巴,大家自己踩一踩看看這個(gè)有什么用!!這個(gè)面試經(jīng)常會(huì)被問(wèn)哦~
到此我們將Symbol的用法整個(gè)過(guò)了一遍,當(dāng)然一般元編程在開(kāi)發(fā)的時(shí)候還是很少用到呢!不過(guò)我們已經(jīng)具備改寫(xiě)js語(yǔ)言本身的能力啦
歡迎持續(xù)關(guān)注公眾號(hào):「前端優(yōu)選」
加我微信:webyouxuan
技術(shù)持續(xù)更新,請(qǐng)持續(xù)關(guān)注