Symbol() 是在 ES6 中提出来的一个新的基础类型,它主要用来定义一个唯一的属性值,防止重复命名,再对象中有着重要的作用,请耐心看完,最下边有 Symbol 进阶,对初学者来说不太友好,若想深入学习js,请务必耐心看完。
一. 基本用法
Symbol() 中接受一个参数作为符号描述,即使描述相同,他俩本身也不会相同。
let symbol = Symbol()
console.log(typeof symbol) // symbol 类型
let symbolA = Symbol('foo')
let symbolB = Symbol('foo')
console.log('symbolA:' , symbolA, 'symbolB:',symbolB) // symbolA: Symbol(foo) symbolB: Symbol(foo)
console.log('symbolA == symbolB',symbolA == symbolB) // symbolA == symbolB false
二. 全局注册 Symbol.for()
同 Symbol() 一样接受一个参数作为符号描述,不同的是, Symbol.for() 在注册前会查询全局注册表中是否存在该描述,不存在则创建,存在则返回该描述。
let symbolC = Symbol.for('石头山')
let _symbolC = Symbol.for('石头山')
console.log(symbolC === _symbolC) // true
const text = Symbol.keyFor(symbolC) // 访问全局注册表,返回对应的键值
console.log(text) // 石头山
三. 实际使用
大多用在对象中定义唯一键值,防止定义重名键值发生冲突。
1. 直接定义
let name = Symbol('author')
const obj = { }
obj[name] = '石头山'
2. 使用 Object.defineProperty()
Object.defineProperty(obj,name,{
value:'石头山'
})
最终都是给 obj 对象中添加了 唯一键值及其对应值 { Symbol(author):'石头山'}
四. Symbol 进阶篇
Symbol键值 | 方法 |
Symbol.hasInstance | instanceof |
Symbol.isConcatSpreadable | Array.concat() |
Symbol.match | String.match() |
Symbol.replace | String.replace() |
Symbol.search | String.search() |
Symbol.specie | --- |
Symbol.split | String.split() |
Symbol.toPrimitive | --- |
Symbol.toStringTag | Object.toString() |
Symbol.unscopables | --- |
看到这里对于刚刚入门的小伙伴来说一定很懵圈,Symbol 常用来定义一些 Object 或者 Function 中的重要方法,我们可以通过 Symbol键值来重写对应的方法,我来给大家重写几个常用的方法,请耐心看完
1. 重写 instanceof
这个方法大家应该都不陌生,用来判断某个实例是否属于某种类型,一下为演示,fA 为 fun 实例,必然打印 ture,由于我们重写,始终返回 false
class fun{
static [Symbol.hasInstance](){
return false
}
}
let fA = new fun()
console.log(fA instanceof fun) // false
2. 重写 String.replace()
该方法返回一个由替换值,替换部分或所有的模式匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,重写后始终返回 石头山
let name_S = ' my name is '
console.log('重写前',name_S.replace(/name/,'Jock')) // my Jock is
RegExp.prototype[Symbol.replace] = function (){
return '石头山'
}
console.log('重写后',name_S.replace(/name/,'shikai')) // 石头山
注:不要在全局中重写,可能造成意想不到的后果,在需要的具体对象或方法中重写即可,有兴趣的小伙伴可以自行测试其他方法。