17. Iterator
https://jiafei2333.github.io/2019/09/16/Generator/
是一种接口,为各种不同的数据结构(Array、Object、Map、Set 等)提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。
一刷:
http://es6.ruanyifeng.com/#docs/iterator
18. Generator
https://jiafei2333.github.io/2019/09/16/Generator/
调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。
1、一个对象如果要具备可被for…of循环调用的 Iterator 接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)。
1/2刷:
http://es6.ruanyifeng.com/#docs/generator
19. Generator 函数的异步应用
http://es6.ruanyifeng.com/#docs/generator-async
一刷,没怎么看明白,可以二刷继续研究,评论也看看。
20.async 函数
http://es6.ruanyifeng.com/#docs/async
async 函数就是 Generator 函数的语法糖。
1、Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。
2、任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
3、Promise 的回调函数( .then )都存放在一个单独的栈里面,而 await 是暂停执行,所以不完全一样。
一刷
12. Symbol
https://jiafei2333.github.io/2019/09/04/Reflect-Symbol/
Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。
1、Singleton 模式指的是调用一个类,任何时候返回的都是同一个实例。
http://es6.ruanyifeng.com/#docs/symbol
一刷:内置的 Symbol 值 这块内容太琐碎了,没怎么记得。
14. Proxy
https://jiafei2333.github.io/2019/09/04/Object.defineProperty-Proxy/
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
1、ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
2、注意,要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作。
3、虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。
4、《this 问题》 这个可以看看,其他的很多都是Proxy的属性
5、Proxy web服务的客户端。
一刷:
http://es6.ruanyifeng.com/#docs/proxy
15. Reflect
Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。
一刷:
http://es6.ruanyifeng.com/#docs/reflect
10. 11. 对象
10.1. 对象的拓展
1.1 属性的遍历
- (1)for…in
- (2)Object.keys(obj)
- (3)Object.getOwnPropertyNames(obj)
- (4)Object.getOwnPropertySymbols(obj)
- (5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
10.1.2 super
我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。
JavaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(方法)。 ??
Object.getPrototypeOf() 返回指定对象的原型。
11.2. 对象的新增方法
11.2.1 Object.is()
比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
1 | Object.is({}, {}); // false |
11.2.2 Object.assign()
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
1 | Object.assign(target, source1, source2); |
- Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。属性名为 Symbol 值的属性,也会被Object.assign拷贝。
11.2.3 proto属性,Object.setPrototypeOf(),Object.getPrototypeOf()
https://jiafei2333.github.io/2019/09/09/Prototype-Extends/
11.2.4 Object.keys(),Object.values(),Object.entries() 搭配 for…of 使用
也都可以搭配数组 for (let index of ['a', 'b'].keys())
一刷:
http://es6.ruanyifeng.com/#docs/object
http://es6.ruanyifeng.com/#docs/object-methods
9. 数组
9.1. 拓展运算符的应用
扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。
Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。
9.2. Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
任何有 length
属性的对象,都可以通过 Array.from
方法转为数组,而此时扩展运算符就无法转换。
一刷:
http://es6.ruanyifeng.com/#docs/array
8. 函数的拓展
8.1. 函数的 length 属性
函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真,这个个数不算。
8.2. 作用域
** http://es6.ruanyifeng.com/#docs/function#%E4%BD%9C%E7%94%A8%E5%9F%9F
8.3. 箭头函数
- (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。下面是一个例子,DOM 事件的回调函数封装在一个对象里面。
1 | var handler = { |
上面代码的init方法中,使用了箭头函数,这导致这个箭头函数里面的this,总是指向handler对象。否则,回调函数运行时,this.doSomething这一行会报错,因为此时this指向document对象。
this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
8.4. 尾调用优化
我们知道,函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。
尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。
一刷:
http://es6.ruanyifeng.com/#docs/function
13. Set和Map数据结构
Set
https://es6.ruanyifeng.com/#docs/set-map
Set本身是一个构造函数,用来生成Set数据结构。它类似于数组,但是成员的值都是唯一的,没有重复的值。
【去重】
1 | let s = new Set([1,2,3,4,5,4,3,2,1]); |
【遍历】
keys()、values()、entries() 搭配 for…of
Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。
Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。
数组的map和filter方法也可以间接用于 Set 了。
WeakSet
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。 ES6 规定 WeakSet 不可遍历。
- WeakSet 的成员只能是对象,而不能是其他类型的值。
- WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
Map
Map也是构造函数,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。