symbol的使用
symbol的概念:
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
特点:
-
值是唯一的,用来解决命名冲突的问题
-
值不能与其他数据进行运算
-
定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
基本使用
// 创建Symbol let y = Symbol(); console.log(y, typeof y); // 添加标示的Symbol let y1 = Symbol("张三") let y2 = Symbol("张三") console.log(y1 === y2); // 使用Symbol for定义 let y3 = Symbol.for("张三") let y4 = Symbol.for("张三") console.log(y3 === y4);
-
Symbol()函数不可以new
-
通过Symbol.keyFor()查看全局符号参数是全局符号返回符号的描述
-
如果传的不是全局符号,返回undefined
-
如果传的不是符号,报错
-
-
使用方式:调用Symbol(标识)函数返回一个符号
-
使用symbol作为对象属性名不被Object.keys等方式访问
-
Symbol类型的Key不能通过Object.keys()或者for...in来枚举,它未被包含在对象自身的属性名集合中,所以,利用该特性,可以把不对外开放的属性用Symbol定义
-
-
使用JSON.stringify(将对象转换成JSON字符串,Symbol属性会被排除在外
如何获取Symbol方式定义的对象属性
object的API: Object.getOwnPropertySymbols(obj)
新增的反射API
-
使用Symbol代替常量
-
我们经常使用常量来代表一种业务逻辑的几种不同的类型,我们希望这些常量是唯一的关系,经常需要为常量赋─个值,常量少的时候还算好,但是常量一多,你可能还得花点脑子好好为他们取个好点的名字。使用Symbol就更加方便了
-
const TYPE_AUDIO = symbol();
-
-
使用Symbol定义类的私有属性/方法
-
在javaScript中,没有如同java等面向对象语言的定义私有属性的private方法,类上所有定义的属性或者方法都是可以公开访问的。有了Symbol以及模块化机制,类的私有属性和方法变得可能。
-
由于Symbol常量PASSWORD被定义在a.,js模块中,外面模块b.js无法获取此Symbol (Symbol是唯一的),因此PASSWORD只能被限定在a.js中使用,使用它来定义类属性外部模块无法访问,达到了私有化的目的。
-
迭代器
什么是迭代器
迭代器也称遍历器(lterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
如何使用迭代器
1、ES6创造了一种新的遍历命令 for...of循环,lterator接口主要供 for...of消费
2、原生具备iterator接口的数据(可用for of遍历) a) Array
b) Arguments
c ) Set d) Map
e) String
f ) TypedArray
g) NodeList
对象的成员可以遍历,是因为该对象实现了lterator接口。比如数组对象:
for (let i of [1,2]) { console.log(i); }
任何数据结构只要部署Iterator接口,就可以完成遍历操作,即依次处理该数据结构的所有成员。
工作原理
1) 创建一个指针对象,指向当前数据结构的起始位置
2) 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
3) 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
4) 每调用next 方法返回一个包含value和done属性的对象
注:需要自定义遍历数据的时候,要想到迭代器。
生成器
什么是生成器Generator
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同, 也可以说它是比较特殊的迭代器
1)首先,生成器函数需要在function的后面加一个符号*:
2)其次,生成器函数可以通过yield关键字来控制函数的执行流程:
3)最后,生成器函数的返回值是一个Generator (生成器)∶
4)生成器事实上是一种特殊的迭代器;
基础使用
function * gen(){ let a = yield'一只没有耳朵"; console.log(a)//返回!!! yield '一只没有尾巴'; return '真奇怪"; } let iterator = gen(); console.log(iterator.next()); console.log(iterator.next('!!!')); console.1og(iterator.next());
代码说明: 1) * 的位置没有限制
2) 生成器函数返回的结果是迭代器对象,调用迭代器对象的next()
方法可以得到yield
语句后的值
3) yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next()
方法,执行一段代码
4) 给next()
传递参数,该实参就是上一个yield
语句返回的结果