《深入理解ES6》阅读笔记 --- Symbol 和 Symbol属性

745 阅读2分钟

Symbol其实解决了两个问题:

  1. 唯一性
  2. 通过Symbol的属性来操作JavaScript内部的逻辑

这个特性的出现为我们定义程序有了普遍的意义,它和原来的六个原始类型一样,也是一个原始类型,你可以调用Symbol()来初始化。

let v = Symbol('icepy')

唯一性

我们知道在JavaScript的世界里,唯一性是很难被描述的,哪怕你用任意的加密函数生成的Key也有可能被撞库,Symbol为我们带来了这样的唯一性:

let name = Symbol('name');
let max = Symbol();
let obj = {
  [name]:'icepy',
  [max]: 29
}

// Symbol()

Symbol可以接收一个参数,这个参数用来des,主要用于程序调试时的跟踪,当然你也可以不传入参数,同样的我们可以通过typeof来判断是否为Symbol类型。

Symbol属性中提供了for方法来处理全局共享的问题,它可以从指定的Symbol注册表中来搜索到具体的内容,反之你可以用keyFor来推断某个Symbol关联的键。

通过Symbol的属性来操作JavaScript内部的逻辑

以前我们比较难去操作JavaScript本身语言内部的逻辑,最多也是在原型链上去定义或者修改某个方法的实现,Symbol的属性中提供了很多去处理程序内部执行的逻辑,如果你有兴趣,可以仔细阅读一下MDN上的文档: Symbol ,这里主要举一个例子来说明:

在以前我们想判断一个数组,可能会这样写:

let f = []
Object.prototype.toString.call(f)
// "[object Array]"

我们可以定义"[object Array]"来判断,但是,假设今天我们写的某些应用程序中,我想将某些类定义出来类型,通过类型的判断,想解决一些问题,最开始我们可能可以用instance来判断是哪个实例,但,这解决不了问题。

有了Symbol属性之后,我们可以改变Object.prototype.toString的返回值。

function Pre(){
}
Pro.prototype[Symbol.toStringTag] = 'Pre';

const me = new Pre();

// Object.prototype.toString.call(me) 
// [object Pre]

可能在这个粗躁的例子中,很难看出来Symbol的作用。

但是,在之前有说到可以通过instance来判断是否为某个类或函数的实例,有一天我想给予它就算它是真实的实例,我也想让它返回false,即:不是一个实例。

function Pre(){

}
Object.defineProperty(Pre,Symbol.hasInstance,{
  value: function(){
     return false
  }
})

这就是Symbol的作用之一,来改变语言程序内部的逻辑。

也许,这些特性在你真实的应用中,很少会用到,不过,看一看,也是没有坏处的。

更多精彩内容可关注我的个人微信公众号:搜索fed-talk