image
说到Symbol就先来说下 js中的基础数据类型 string、number、boolean、null、undefined,Symbol就是js中的第六种基础数据类型
用一句话来描述Symbol,那就是独一无二!
Symbol的使用
基本使用
consts1 = Symbol('song');
consts2 = Symbol('song');
// Symbol中的标识一般放number、string
console.log(s1 === s2);// Symbol声明的变量不相等
Symbol作为key
consts1 = Symbol('song');
letobj = {
[s1]:'song',// es6语法[] 可以将symbol的值作为属性
age:18
}
for(letkeyinobj){// for循环无法遍历symbol属性
console.log(obj[key])
}
// Reflect.ownKeys方法可以拿到所有的key属性
Reflect.ownKeys(obj).forEach(key=>{
console.log(obj[key]);
})
Symbol.for
我们上面说symbol是独一无二的,但是有的时候我希望可以复用声明过的symbol,可以使用for语法,如果symbol不存在则声明,如果存在则将创建过的symbol返回回来!
consts1 = Symbol.for('song');
consts2 = Symbol.for('song');
console.log(s1 === s2);
console.log(Symbol.keyFor(s2));// 可以通过keyFor 获取symbok的key
Symbol元编程
元编程:可以去对原生js的操作进行修改,说白了就是可以更改原生js的行为
ES6提供了11个内置的Symbol值
1.Symbol.hasInstance
重写instanceof默认行为
constinstance = {
[Symbol.hasInstance](value){
return'a'invalue
}
}
// 当调用 instanceof 方法,会默认调用instance上的hasInstance方法
console.log({a:1}instanceofinstance)
2.Symbol.isConcatSpreadable
重写数组的展开行为
constarr = [1,2,3];
arr[Symbol.isConcatSpreadable] =false;
console.log(arr.concat([1,2,3]));
3.Symbol.match / split / search / replace
重写字符串的match,split,search方法
constobj = {
[Symbol.match](value){
returnvalue.length ===3
}
}
console.log('abc'.match(obj));
4.Symbol.species
创建衍生对象时,指定构造函数
classMyArray extendsArray{
constructor(...args){
super(...args);
}
static get [Symbol.species](){
returnArray;// 创建衍生对象会用Array作为构造函数
}
}
constarr =newMyArray(1,2,3);
constnewArr = arr.map(item=>item*2);
console.log(newArrinstanceofMyArray);// 默认衍生对象也是MyArray的实例
5.Symbol.toPrimitive
重写数据类型转化
constobj = {
[Symbol.toPrimitive](type){// type number string default
return123;
}
}
console.log(obj*123);
6.Symbol.toStringTag
重写toString方法
constobj = {
[Symbol.toStringTag]:"xxx"
};
console.log(Object.prototype.toString.call(obj));// [object xxx]
7.Symbol.unscopables
重写哪些属性被with所排除
console.log(Array.prototype[Symbol.unscopables]);// 哪些方法不能再with中使用
with(Array.prototype){// 直接调用数组原型上的方法
forEach.call([1,2,3],element => {
console.log(element)
});
}
classMyClass {
eat() {}
get [Symbol.unscopables]() {
return{ eat:true};// 不能在with下使用
}
}
with(MyClass.prototype) {
console.log(eat);
}
还差最后一个Symbol.iterator,留个小尾巴,大家自己踩一踩看看这个有什么用!!这个面试经常会被问哦~
到此我们将Symbol的用法整个过了一遍,当然一般元编程在开发的时候还是很少用到呢!不过我们已经具备改写js语言本身的能力啦
欢迎持续关注公众号:「前端优选」
加我微信:webyouxuan
技术持续更新,请持续关注