前面我们介绍了迭代器的本质在于 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 在很多对象操作方法中都是拿不到的,更像是一个隐身的键,在有类似需求的时候是不错的选择。
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
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
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