一、Symbol
1.创建一个Symbol
let s1 = Symbol() s1=>Symbol
创建出来的Symbol表示一个独一无二的值,symbol和对象不一样,不能给他添加属性
let s1 = Symbol('foo') //引号里为描述信息
let s2 = Symbol('bar')
let s3 = Symbol('head')
console.log(typeof s1);
console.log(s1,s2,s3);
console.log(s1 == s2); //不相等
console.log(s1.description); //获取Symbol的描述信息
//Symbol一定不能使用new操作符操作
2.消除魔术字符串
let area = 0
let s1 = Symbol('Triangle')
let shapeType = {
Triangle:'s1'
}
function getArea(shape,options){
switch(shape){
case 'shapeType.Triangle': //魔术字符串
area = .5 * options.width * options.height
break;
}
return area;
}
let r =getArea('shapeType.Triangle',{width:10,height:10})
console.log(r);
3.获取⼀个对象中Symbol属性名Symbol
let s1 = Symbol('gender')
let obj = {
name:'tom',
age:12,
[s1]:'男' //将Symbol作为属性名,保证属性名不会重复,但是这个属性是一个私有属性
}
// console.log(obj);
// for (let item in obj){
// console.log(item); //拿不到Symbol属性
// }
let a = Object.getOwnPropertySymbols(obj) //可以获取Symbol属性;获取指定对象的所有 Symbol 属性名
console.log(a);
let r = Reflect.ownKeys(obj) //获取所有的属性名
console.log(r);
4.Symbol值重复利⽤
(1)Symbol.for()⽅法可以做到使⽤同⼀个 Symbol 值。它接受⼀个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。
如果有,就返回这个 Symbol 值,否则就新建⼀个以该字符串为名称的 Symbol 值,并将其注册到全局。
let s1 = Symbol.for('foo') //将s1注册到全局,不管他在不在全局
let s2 = Symbol.for('foo') //将s1注册到全局,不管他在不在全局
console.log(s1 == s2); //true
(2)Symbol.keyFor()⽅法返回⼀个已登记的 Symbol 类型值的key
let r = Symbol.keyFor(s1)
console.log(r);
5.内置Symbol
Symbol.iterator 获得指定对象的遍历器方法
let r = [][Symbol.iterator] r是个方法,调用r会产生一个迭代器对象,这个迭代器对象就可以使用next方法
let str = 'hello world'
let r = str[Symbol.iterator] //获取到一个迭代器方法
let a = str[Symbol.iterator]() //获取到一个迭代器方法
let b = str[Symbol.iterator]().next() //获取到一个迭代器方法
for of适应于所有的可迭代元素
for(let item of str){
console.log(item);
}
console.log(r);
console.log(a);
console.log(b);
二、迭代器
1.当需要对⼀个对象进⾏迭代时(⽐如开始⽤于⼀个for..of循环中),它的Symbol.i terator⽅法都会在不传参情况下被调⽤,返回的迭代器⽤于获取要迭代的值。
2.⼀些内置类型拥有默认的迭代器⾏为,如下:
(1)Array.prototype[Symbol.iterator]()
(2)TypedArray.prototype[Symbol.iterator]()
(3)String.prototype[Symbol.iterator]()
(4)Map.prototype[Symbol.iterator]()
(5)Set.prototype[Symbol.iterator]()
3.Iterator 的遍历过程如下:
(1)创建⼀个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是⼀个指针对象。
(2)第⼀次调⽤指针对象的next⽅法,可以将指针指向数据结构的第⼀个成员。
(3)第⼆次调⽤指针对象的next⽅法,指针就指向数据结构的第⼆个成员。
(4)不断调⽤指针对象的next⽅法,直到它指向数据结构的结束位置。每⼀次调⽤next⽅法,都会返回数据结构的当前成员的信息。
具体来说,就是返回⼀个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是⼀个布尔值,表示 遍历是否结束。
4.调⽤ Iterator 接⼝的场合
(1)扩展运算符
(2)yield *
(3)for...of
(4)Array.from()
(5)Map(), Set(), WeakMap(), WeakSet()(⽐如new Map([['a',1],['b',2]]))
(6)Promise.all()
(7)Promise.race()
let arr = [1,2,3,4,5]
// arr[Symbol.iterator] //方法
console.log(arr[Symbol.iterator]);
// arr[Symbol.iterator]()
console.log(arr[Symbol.iterator]() ); //迭代器对象
// arr[Symbol.iterator]().next()
console.log(arr[Symbol.iterator]().next() ); //{value:1,done:false}
let set = new Set('hello') //传入一个可以迭代的数据结构
console.log(set);