- Symbol的使用
- 迭代器
- 生成器
1.Symbol的使用
1.1-什么是Symbol
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
1.2-Symbol特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for..in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名
1.3-基本使用
<script>
// 创建Symbol
let s1 = Symbol();
console.log(s1, typeof s1);
// 添加标识的Symbol
let s2 = Symbol('张三');
let s2_2 = Symbol('张三');
console.log(s2 === s2_2)
// 使用Symbol for定义
let s3 = Symbol.for('张三')
let s3_2 = Symbol.for('张三')
console.log(s3 === s3_2); //true,使用symbol.for()来实现
</script>
注:遇到唯一性的场景是要想到Symbol
1.4-Symbol()函数不可以new
符号代表唯一的值,但是我就想用一个符号呢?
通过Symbol.for()创建一个全局符号
const a = Symbol('a');
const b = Symbol.for('b');
const b2 = Symbol.for('c');
const obj = {
[a]: 1,
[b]: 2,
[b2]: 3
};
console.log(b === b2); //true
console.log(obj);
通过Symbol.keyFor()查看全局符号参数是全局符号返回符号的描述
如果传的不是全局符号返回undefined
如果传的不是符号报错
let c = Symbol.for("Hello")
console.log(Symbol.keyFor(c));
1.5-使用方法:调用Symbol(标识)函数返回一个符号
const a = Symbol('a');
const obj = {
[a]:1
};
console.log(obj) //{Symbol(a):1}
1.6-使用Symbol作为对象属性名不被Object.keys等方式访问
let obj = {
[Symbol("name")]: "一斤代码",
age: 18,
title: "Engineer",
}
console.log(Object.keys(obj)); //['age','title']
for (let p in obj) {
console.log(p); //age title
}
console.log(Object.getOwnPropertyNames(obj)); //['age','title']
输出结果如下:
由上可知,Symbol类型的Key不能通过Object.keys()或者for..in来枚举,它未被包含在对象自身的属性名集合中,所以,利用该特性,可以把不对外开放的属性用Symbol定义
1.7-使用JSON.stringify()将对象转换成JSON字符串,Symbol属性会被排除在外
let obj2 = JSON.stringify(obj2)
console.log(obj2);
1.8-如何获取Symbol方式定义的对象属性
(1)object的APl:Object.getOwnPropertySymbols(obj)
(2)新增的反射API
console.log(Object.getOwnPropertySymbols(obj)); //[Symbol(name)]
// 利用了反射API
console.log(Reflect.ownKeys(obj)); //['age','title',Symbol(name)]
1.9-使用Symbol代替常量
我们经常使用常量来代表一种业务逻辑的几种不同的类型,我们希望这些常量是唯一的关系,经常需要为常量赋一个值,常量少的时候还算好,但是常量一多,你可能还得花点脑子好好为他们取个好点的名字。
1.10-Symbol内置值
除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。可以称这些方法为靡术方法.因为它们会在特定的场景下白动执行.
2.迭代器
2.1-什么是迭代器
迭代器也称遍历器(lterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
2.2-如何使用迭代器
- ES6创造了一种新的遍历命令for....of循环,lterator接口主要供for....of消费
- 原生具备iterator接口的数据(可用for of遍历)
Array
Arguments
Set
Map
String
TypedArray
NodeList
对象的成员可以遍历,是因为该对象实现了Iterator接口。比如数组对象:
for (let i of [1,2]) {
console.log(i);
}
任何数据结构只要部署Iterator接口,就可以完成遍历操作,即一次处理改数据结构的所有成员
2.3-工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
注:需要自定义遍历数据的时候,要想到迭代器。
3.生成器
3.1-什么是生成器Generator
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
- 首先,生成器函数需要在function的后面加一个符号*:
- 其次,生成器函数可以通过yield关键字来控制函数的执行流程:
- 最后,生成器函数的返回值是一个Generator (生成器)∶
- 生成器事实上是一种特殊的迭代器;
3.2基础使用
function* gen() {
yield "一只兔子";
yield "一只猫";
yield "一只狗"
}
let result = gen()
console.log(result.next());
console.log(result.next());
console.log(result.next());
console.log(result.next());