迭代器(iterator)
迭代器(iterator),使用户在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节
即:迭代器是帮助我们队某个数据结构进行遍历的对象
迭代器也是一个具体的对象,这个对象需要符合迭代器协议—一个特定的next方法
next方法有如下要求:
- 一个无参数或者一个参数的函数,返回一个应当拥有以下两个属性的对象:
2.done(boolean)
- 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)
- 如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依 然存在,即为迭代结束之后的默认返回值。
- value
- 迭代器返回的任何 JavaScript 值。done 为 true 时可省略。
可迭代对象
注意:迭代器≠可迭代对象
总结:当一个对象内部实现了迭代器协议时候(对象内部实现迭代器),它就是一个可迭代对象。当一个对象变成了可迭代对象时,就可以进行某些操作(例如: for…of)。代码中我们使用 Symbol.iterator 访问该属性
可迭代对象的应用
事实上我们平时创建的很多原生对象已经实现了可迭代协议,会生成一个迭代器对象的:
例如:String、Array、Map、Set、arguments对象、NodeList集合
应用:
- JavaScript中语法:for ...of、展开语法(spread syntax)、yield*(后面讲)、解构赋值(Destructuring_assignment);
- 创建一些对象时:new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable]);
- 一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);
生成器
生成器函数也是一个函数(一个特殊的迭代器),但是和普通的函数有一些区别:
- 首先,生成器函数需要在function的后面加一个符号:*
- 其次,生成器函数可以通过yield关键字来控制函数的执行流程:
- 最后,生成器函数的返回值是一个Generator(生成器):
生成器事实上是一种特殊的迭代器;
MDN:Instead, they return a special type of iterator, called a Generator.
生成器传递参数–next函数
函数既然可以分段执行,那么就可以分段传递参数
我们在调用next 的时候,可以给它传递参数,那么这个参数会作为上一个yield语句的返回值
注意:我们可以提前结束生成器–通过return函数
return传值后这个生成器就会结束,之后调用next不会继续生成值了。
生成器替代迭代器
异步函数(async function)
异步函数有返回值时,和普通函数会有区别:
- 情况一:异步函数也可以有返回值,但是异步函数的返回值相当于被包裹到Promise.resolve中;
- 情况二:如果我们的异步函数的返回值是Promise,状态由会由Promise决定;
- 情况三:如果我们的异步函数的返回值是一个对象并且实现了thenable,那么会由对象的then方法来决定;
注意:如果我们在async中抛出异常,那么程序并不会报错,而是会作为Promise 的reject来传递
await 关键字
- 通常使用await是后面会跟上一个表达式,这个表达式会返回一个Promise;
- 那么await会等到Promise的状态变成fulfilled状态,之后继续执行异步函数;
注意:
- 如果await后面是一个普通的值,那么会直接返回这个值;
- 如果await后面是一个thenable的对象,那么会根据对象的then方法调用来决定后续的值;
- 如果await后面的表达式,返回的Promise是reject的状态,那么会将这个reject结果直接作为函数的Promise的reject值;
throw 关键字
如何可以让一个函数告知外界自己内部出现了错误呢?
通过throw关键字,抛出一个异常;
throw语句:
- throw语句用于抛出一个用户自定义的异常;
- 当遇到throw语句时,当前的函数执行会被停止(throw后面的语句不会执行);
hrow关键字可以跟上哪些类型呢?
- 基本数据类型:比如number、string、Boolean
- 对象类型:对象类型可以包含更多的信息
Error 类型
JavaScript已经给我们提供了一个Error类,我们可以直接创建这个类的对象。
Error包含三个属性:
- messsage:创建Error对象时传入的message;
- name:Error的名称,通常和类的名称一致;
- stack:整个Error的错误信息,包括函数的调用栈,当我们直接打印Error对象时,打印的就是stack;
Error有一些自己的子类:
- RangeError:下标值越界时使用的错误类型;
- SyntaxError:解析语法错误时使用的错误类型;
- TypeError:出现类型错误时,使用的错误类型;
函数异常处理和异常的捕获
一个函数抛出了异常,调用它的时候程序会被强制终止。如果函数抛出了异常,但是我们并没有对这个异常进行处理,那么这个异常会继续传 递到上一个函数调用中; 而如果到了最顶层(全局)的代码中依然没有对这个异常的处理代码,这个时候就会报错并且终止程序的运行。
我们可以使用 try catch对抛出异常进行捕获
Storage
WebStorage主要提供了一种机制,可以让浏览器提供一种比cookie更直观的key、value存储方式:
- localStorage:本地存储,提供的是一种永久性的存储方法,在关闭掉网页重新打开时,存储的内容依然保留;
- sessionStorage:会话存储,提供的是本次会话的存储,在关闭掉会话时,存储的内容会被清除;