一个JS小白,没有什么项目经验,看书上十页的Symbol介绍后,完全不懂为什么要设计它。
辛苦理解学长的解答,写一下笔记。
如有错处,感谢指出!(QAQ希望温柔点。
一、先知道Symbol的基本用法
Symbol(符号)用于生成唯一的标识
let s1 = Symbol('这个字符串相当于注释')
let s2 = Symbol('这个字符串相当于注释')
console.log(s1==s2) //输出false
//还有一种是在全局符号注册表创建符号,使用Symbol.for()
//我们先理解Symbol,先不管这个
上面的输出是 false,因为即使括号里传进的字符串是一样的,每次调用Symbol生成的标识符都是唯一的,s1和s2分别代表不同的标识。
二、设计Symbol的本质目的
Symbol生成唯一标识,可以使对象的属性具有唯一标识,避免同名属性冲突(避免新的属性定义覆盖旧的属性定义)。
举例子:
① 假如不存在Symbol,正则对象的原型上有个用于匹配的函数叫regMatch。String.prototype.match默认调用传入的正则对象原型上的regMatch,来转换正则表达式的值,并匹配。
function regConstructor(regExp){
this.regExp = regExp
}
regConstructor.prototype.regMatch=function(str){
/*将regExp按照正则表达式的规则转换,进行匹配并返回结果*/
console.log('you got here')
}
function String(str){
this.str = str
}
String.prototype.match=function(regExp){
return regExp.regMatch(this.str)
}
let regExp = new regConstructor(/bar/)
let str = new String('foobar')
//如果我给regExp又定义一个属性名为regMatch的方法,而且意图不一定是要改写匹配规则
//可能只是无意中重名了,会覆盖原型上的重名属性
regExp.regMatch=function(){console.log('OMG!')}
str.match(regExp)//输出 OMG
②因此,干脆给原型上的regMatch一个唯一标识,Symbol值是什么不重要,让固定调用它的方法知道是它就行了。
let regMatch = Symbol('我相当于注释,其实语言给我们固定了常用内置符号,这里我们叫它regMatch')
function regConstructor(regExp){
this.regExp = regExp
}
regConstructor.prototype={
[regMatch]:function(str){
/*将regExp按照正则表达式的规则转换,进行匹配并返回结果*/
console.log('you got here')
}
}
function String(str){
this.str = str
}
String.prototype.match=function(regExp){
return regExp[regMatch](this.str)
}
let regExp = new regConstructor(/bar/)
let str = new String('foobar')
regExp.regMatch=function(){console.log('OMG!')} //根本没有叫regMatch的属性,不会有覆盖
str.match(regExp)//输出 you got here
Symbol还有很多附加用法,但我觉得先理解为什么,再理解怎么用会好些。