每周分享:类型新成员 Symbol

前面我们介绍了迭代器的本质在于 Symbol.iterator 这个属性

let obj = {}
obj[Symbol.iterator] =  () => { ... }

一般来说对象的 key 都是一个字符串,而这里的 Symbol.iterator 也是一个字符串吗?很明显不是的,这是一个 symbol 类型的值,它和 string,number,boolean,null,undefined 一起组成了 JavaScript 的 6 种基本数据类型。

自定义 symbol

我们可以通过下面的语法定义自己的 symbol

Symbol([描述])

注意,不能使用 new Symbol()。这里的描述主要用于调试的时候方便查看,比如

var sym1 = Symbol('hello')
var sym2 = Symbol('hello')

由于 symbol 具有唯一性,所以上面两个即便描述一样,但是却不相等

sym1 === sym2
// false

除了这种方式,还可以用 Symbol.for(key) 语法,使用一个唯一 key 搜索现有的 symbol,找到了就返回,没有找到就创建一个新的

var sym3 = Symbol.for('key')
var sym4 = Symbol.for('key')

sym3 === sym4
// true

其实这种方式主要是用来查找已经存在的 symbol,不建议用来创建新的 symbol。创建好的 symbol 就可以用在一个对象的键中了

var man = {}
var key = Symbol('age')

man[key] = 25

console.log(man[key])
// 25

注意,由于 symbol 的特殊性,在用作 key 的时候只能是括号语法(obj[symbol]),而不能是点语法(obj.symbol)。

内置 symbol

除了 Symbol.iterator,还有一些其它的内置 symbol,比如 Symbol.search 用在字符串搜索 String.prototype.search() 方法中

var str = 'hello'

'hello'.search('o')
// 4

let mySearch = {}
mySearch[Symbol.search] = () => {
  return '弄啥呢'
}


'hello'.search(mySearch)
// '弄啥呢'

可见 search() 方法确实使用了 Symbol.search 。

枚举

var man = {
  name: 'tom'
}
var key = Symbol('age')

man[key] = 25

Object.keys(man)
// ["name"]

因为 symbol 类型的属性是不可枚举的,自然也不能被 for...in 遍历到,包括 getOwnPropertyNames 也是拿不到的

Object.getOwnPropertyNames(man)
// ["name"]

此外 JSON.stringify() 也拿它没办法

JSON.stringify(man)
// "{"name":"tom"}"

所以要拿到 symbol 类型的键,只能通过一个特殊的方法 getOwnPropertySymbols

Object.getOwnPropertySymbols(man)
// [Symbol(age)]

因此我们可以拿到一个数组的迭代器 symbol 属性(在其原型上)

Object.getOwnPropertySymbols([].__proto__)
// (2)[Symbol(Symbol.iterator), Symbol(Symbol.unscopables)]

其实还可以用 Reflect.ownKeys(),用于返回一个对象自身的所有属性,它等价于 Object.getOwnPropertyNames()Object.getOwnPropertySymbols() 之和

Reflect.ownKeys(man)
// [Symbol(age)]

可见,symbol 类型的 key 在很多对象操作方法中都是拿不到的,更像是一个隐身的键,在有类似需求的时候是不错的选择。

最新评论

  1. Have you ever considered writing an e-book or guest authoring on other sites? I have a blog centered on the same topics you discuss and would love to have you share some stories/information. I know my subscribers would appreciate your work. If you are even remotely interested, feel free to shoot me an e-mail. Sergio Loli

  2. Have you ever thought about publishing an ebook or guest authoring on other blogs? I have a blog centered on the same information you discuss and would really like to have you share some stories/information. I know my subscribers would appreciate your work. If you are even remotely interested, feel free to shoot me an email. Jefferson Castorena

  3. Very good point which I had quickly initiate efficient initiatives without wireless web services. Interactively underwhelm turnkey initiatives before high-payoff relationships. Holisticly restore superior interfaces before flexible technology. Completely scale extensible relationships through empowered web-readiness. Mohamed Coulibaly

bahis oyna进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注