参考:TypeScript Symbols
symbol 是自ECMAScript 2015起,成为的一种新的原生类型,就像number和string一样。
symbol 类型的值是通过Symbol 构造函数创建的,作用是作为一种唯一标识的参数,只支持string 和 number类型的参数。
// 创建symbol类型参数
let sym1 = Symbol()
let sym2 = Symbol("key value") //可以传入可选参数(string 和 number)
Symobol 构造函数即使两个完全一样的可选参数,创建的 symbol 类型参数也是不相等的。
const sym1 = Symbol()
const sym2 = Symbol()
console.log( sym1 === sym2 ) //false
// 创建symbol类型变量
let sym = Symbol()
// 用作对象属性的键
let obj = {
[sym]: "hello world"
}
// 可以直接读取对象的属性,但是注意普通的遍历方法无效
console.log(obj[sym]) //hello world
// 创建一个含有symbol类型键的对象
let sym1 = Symbol('one')
let sym2 = Symbol('two')
const obj = {
[sym1]: 'hello world',
[sym2]: 'hello Typescript',
a: 123,
}
// 1. for in 遍历无法获取
for(const key in obj) {
console.log(key) //a
}
// 2. Object.keys 遍历无法获取
console.log(Object.keys(obj)) //['a']
// 3. getOwnPropertyNames 遍历无法获取
console.log(Object.getOwnPropertyNames(obj)) //['a']
// 4. JSON.stringfy 输出无法获取
console.log(JSON.stringify(obj)) //{"a": 123}
// 创建一个含有symbol类型键的对象
let sym1 = Symbol('one')
let sym2 = Symbol('two')
const obj = {
[sym1]: 'hello world',
[sym2]: 'hello Typescript',
a: 123,
}
// 1. Object.getOwnPropertySymbols
// 作用:只获取具体的symbol属性,有几个获取几个
console.log(Object.getOwnPropertySymbols(obj)) //[ Symbol(one), Symbol(two) ]
// 2. es6的 reflect 可以拿到对象所有的属性
console.log(Reflect.ownKeys(obj)) //[ 'a', Symbol(one), Symbol(two) ]
Symbol.iterator 被大部分类型拥有,比如Array、Map、Set、String、TypedArray、nodeList对象和函数argumetns参数。
Symbol.iterator 是上面提到的类型本身带有的方法,调用该方法会返回一个迭代器对象,该迭代器对象是专门为 for of语法服务的,也就是说使用了Symbol.iterator 方法就会获取将上述类型内容变为可以使用for of遍历的数据。
使用示例:ArraySymbol.iterator,简单理解就是** Array调用原型下的[Symbol.iterator]这个属性的方法**。
// 创建数组,调用数组下 Symbol.iterator 方法
var arr = [1, 2, 3, 4]
let it: IterableIterator<number> = arr[Symbol.iterator]()
// 使用 for of 去遍历返回的对象
for( let item of it ){
console.log(item) //1,2,3,4
}
在返回的迭代器对象下,有next方法,这其实是java中迭代器类下的方法,可以具体参考,帮助理解。
// 创建数组,调用数组下 Symbol.iterator 方法
var arr = [1, 2, 3, 4]
let it: IterableIterator<number> = arr[Symbol.iterator]()
// 使用 for of 去遍历返回的对象
console.log(it.next().value); //1
console.log(it.next().value); //2
console.log(it.next().value); //3
console.log(it.next().value); //4
调用next方法可以返回一个包含迭代值和done字段的对象,在每次执行next方法都会改变迭代器里面默认指针指向的那位数据。
因此不要在使用for of语法遍历后再去使用 next方法,会输出 undefined。