1.ES6模块

  • 在ES6前,实现模块化使用的是RequireJS或者是seaJS(分别是基于AMD规范的模块化库,和基于CMD规范的模块化库)
  • ES6引入了模块化,其设计思想是在编译时就能确定的依赖关系,以及输入输出的变量
  • ES6的模块化分为导入和导出两个模块
  • 特点
    • ES6模块自动开启严格模式
    • 模块可以导入和导出各种类型的变量
    • 每个模块都有自己的上下文,每一个模块内声明的都是局部变量
    • 每个模块只加载一次(是单例的),若再去加载同目录下的文件,直接从内存中读取
  • 基本用法
    • 导出的函数声明与类声明必须要有名称(export default命令另外考虑)
    • 不仅能导出声明还能导出引用
    • export命令可以出现在模块的额任何外置,但必须位于模块顶层
    • import命令会提升到整个模块的头部,首先执行
    • 加以使用大括号指定所要输出的一组变量写在文档尾部,明确导出的接口
    • 函数与类都需要有对应的名称,导出文档尾部也避免了无对应名称
 1 //test.js
 2 let myName = 'Tom';
 3 let myAge = 20;
 4 let fn = function(){
 5     return "my name is "+myName+" and I'm "+myAge;
 6 }
 7 let myClass = class myClass{
 8     static a = 'yeah!';
 9 }
10 export{myName,myAge,fn,myClass}
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title></title>
 6     </head>
 7     <body>
 8         <!--注意type为module-->
 9         <script type="module">
10             import{myName,myAge,fn,myClass} from "./js/test.js";
11             console.log(myName);//Tom
12         </script>
13     </body>
14 </html>

 

  • as的使用
1 let myName = 'Tom';
2 // 使用as重新定义导出的接口名称,隐藏模块的内部变量
3 export{myName as name}
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="module">
 9             import{name} from "./js/test.js";
10             console.log(name);//Tom
11         </script>
12     </body>
13 </html>
  • import命令的特点
    • 只读属性,不允许在家在模块的脚本里面,改写接口的引用指向,既可以改写import变量类型为对象的属性值,不能改写import变量类型为基本类型的值
    • 单例模式,多次重复执行同一句import语句,那么只会执行一次,而不会执行多次,声明不同接口引用,会声明对应变量但只执行一次import,import是静态执行,所以不能使用表达式和变量
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="module">
 9             import{name} from "./js/test.js";
10             import{myAge} from "./js/test.js";
11             //相当于import{name,myAge} from "./js/test.js";
12         </script>
13     </body>
14 </html>

 

  • export default命令
    • 在同一个文件或模块中,export、import可以有多个,export default仅有一个
    • export default中的default是对应的导出接口变量
    • 通过export方式导出,在导入时要加{},export default则不需要
    • export default向外暴露成员,可以使用任意变量来接受
1 var a = "kiki";
2 export default a;//仅有一个
3 import b from "./test.js"
4 //不需要加{}使用任意变量接收
  • 复合使用
    • 可以将导出接口改名,包括default
    • 复合使用export与import,也可以导出全部,当前模块导出的接口会覆盖继承导出的
 1 export {foo, bar} from "methods"
 2 //约定于下面两段语句,不过上面导入导出方式该模块没有导入foo与bar
 3 import {foo, bar} from "methods"
 4 export {foo, bar}
 5 /**    特点1   **/
 6 //普通改名
 7 export {foo as a} from "methods"
 8 //将foo转导成default
 9 export {foo as default} from "methods"
10 //将default转导成foo
11 export {default as foo} from "methods"
12 /**    特点2   **/
13 export * from "methods"

 2.ES6 Promise对象

  是异步编程的一种解决方案。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。

  • Promise状态:除了异步操作的结果,任何其他操作都无法改变这个状态
    • pending:进行中
    • fulfilled:已成功
    • rejected:已失败
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //promise对象只有:从pending变为fulfilled和从pending变为rejected状态
10             // 只要处于fulfilled和rejected,状态就不会再改变了即resolved(已定型)
11             const p1 = new Promise(function(resolve,reject){
12                 resolve('success1');
13                 resolve('success2');
14             })
15             const p2 = new Promise(function(resolve,reject){
16                 resolve('success3');
17                 resolve('reject');
18             })
19             p1.then(function(value){
20                 console.log(value);//success1
21             })
22             p2.then(function(value){
23                 console.log(value);//success3
24             })
25         </script>
26     </body>
27 </html>
  • 状态的缺点
    • 无法取消Promise,一旦新建它就会立即执行,无法中途取消
    • 如果不设置回调函数,Promise内部抛出错误,不会反映到外部
    • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
  • then方法
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //then方法接受两个函数作为参数
10             //第一个参数:Promise执行成功时的回调
11             //第二个参数:Promise执行失败后的回调
12             //两个函数只有一个会被调用,在JS事件队列的当前运行完成之前,回调函数永远不会被调用
13             const p = new Promise(function(resolve,reject){
14                 resolve("success");
15             })
16             p.then(function(value){
17                 console.log(value);
18             })
19             console.log('first');
20             //first
21             //success
22             //注意:通过.then添加的回调函数,不论什么时候都会被调用,
23             //可以添加多个回调函数,他们会按照插入顺序并且独立运行
24         </script>
25     </body>
26 </html>

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             const p = new Promise(function(resolve,reject){
10                 resolve(1);
11             }).then(function(value){//第一个then
12                 console.log(value);
13                 return value*2;
14             }).then(function(value){//第二个then
15                 console.log(value);
16             }).then(function(value){//第三个then
17                 return Promise.resolve('resolve');
18             }).then(function(value){//第四个then
19                 console.log(value);
20                 return Promise.reject('reject');
21             }).then(function(value){//第五个then
22                 console.log('resolve: '+value);
23             },function(err){
24                 console.log('reject',err);
25             })
26             /* 
27              打印结果:
28                         1
29                         2
30                         resolve
31                         reject reject 
32              then方法将返回一个resolved或rejected状态的Promise对象便于链式调用,
33              且Promise对象的值也是这个返回值
34             */
35         </script>
36     </body>
37 </html>
  • then方法注意点
    • 简便的Promise链式编程最好扁平化,不要嵌套Promise。注意总是返回或终止Promise链

3.Generator函数

  ES6引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供了解决方案

  • Generator函数组成
    • 一是在function后面,函数名之前有个*
    • 函数内部有yield表达式(定义函数内部的状态)
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function* func(){
10                 console.log("one");
11                 yield'1';
12                 console.log("two");
13                 yield '2';
14                 console.log("three");
15                 return '3';
16             }
17         </script>
18     </body>
19 </html>
  • 执行机制
    • 调用Gnerator函数和调用普通函数一样,在函数名后面加上()即可。但是Generator函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针,所以要调用遍历器对象的next方法,指针就会从函数头部或者上一次停下来的地方开始执行
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function* func(){
10                 console.log("one");
11                 yield '1';
12                 console.log("two");
13                 yield '2';
14                 console.log("three");
15                 return '3';
16             }
17             var f = func();
18             //第一次调用next方法时,从Generator头部开始执行,打印了'one'
19             //执行到yield后就停下来,yield后面的值作为返回对象的value属性
20             //此时函数没有执行完,返回对象的done为false
21             console.log(f.next());
22             //one
23             //{value: '1', done: false}
24             console.log(f.next());
25             //two
26             //{value: '2', done: false}
27             console.log(f.next());
28             //three
29             //{value: '3', done: true}
30         </script>
31     </body>
32 </html>

 

  • 函数返回遍历器对象的方法
    • next方法
      • 当next的方法不传入参数时,yiled的返回值是undefined
      • 当next传入参数时,该参数会作为上一步yiled的返回值
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function* sendParameter(){
10                 console.log("start");
11                 var x = yield '1';
12                 console.log("one: "+x);
13                 var y = yield '2';
14                 console.log("two: "+y);
15                 console.log("total: "+(x+y));
16             }
17             //next不传参
18             var sendp1 = sendParameter();
19             console.log(sendp1.next());
20             //start
21             //{value: '1', done: false}
22             console.log(sendp1.next());
23             //one: undefined
24             //{value: '2', done: false}
25             console.log(sendp1.next());
26             //two: undefined
27             //total: NaN
28             //{value: undefined, done: true}
29             //next传参
30             var sendp2 = sendParameter();
31             console.log(sendp2.next(10));
32             //start
33             //{value: '1', done: false}
34             console.log(sendp2.next(20));
35             //one: 20
36             //{value: '2', done: false}
37             console.log(sendp2.next(30));
38             //two: 30
39             //total: 50
40             //{value: undefined, done: true}
41             //除了使用next,还可以使用for…of…循环遍历Generator函数产生的Iterator对象
42         </script>
43     </body>
44 </html>

 

  • return方法
    • return方法返回给定值,并结束遍历Generator函数
    • return方法提供参数时,返回该参数;不提供参数时,返回undefined
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function* foo(){
10                 yield 1;
11                 yield 2;
12                 yield 3;
13             }
14             var f = foo();
15             console.log(f.next());//{value: 1, done: false}
16             console.log(f.return("foo"));//{value: 'foo', done: true}
17             console.log(f.next());//{value: undefined, done: true}
18             console.log("-------------------------------");
19             //throw
20             //throw方法可以在Generator函数体外面抛出异常,在函数体内部捕获
21             //遍历对象抛出两个错误,第一个Generator函数内部捕获,
22             //第二个因为函数体内部的catch已经执行过了所以不会再捕获这个错误,
23             //所以这个错误抛出Generator函数体,被函数体外部的catch捕获
24             var g = function* (){
25                 try{
26                     yield;
27                 }catch(e){
28                     console.log('catch inner',e);
29                 }
30             };
31             var i = g();
32             i.next()
33             try{
34                 i.throw("a");
35                 i.throw("b");
36             }catch(e){
37                 console.log('catch outsider',e);
38             }
39             //catch inner a
40             //catch outsider b
41         </script>
42     </body>
43 </html>
  • yield*表达式
    • yield表达式表示yield返回一个遍历器对象,用于在Generator函数内部,调用另一个Generator函数 
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function* callee(){
10                 console.log('callee: '+(yield));
11             }
12             function* caller(){
13                 while(true){
14                     yield* callee();
15                 }
16             }
17             const callerObj = caller();
18             console.log(callerObj.next());
19             //{value: undefined, done: false}
20             console.log(callerObj.next('a'));
21             //callee: a
22             //{value: undefined, done: false}
23             console.log(callerObj.next('b'));
24             //callee: b
25             //{value: undefined, done: false}
26             //等同于
27             // function* caller(){
28             //     while(true){
29             //         for(var value of callee){
30             //             yield value;
31             //         }
32             //     }
33             // }
34         </script>
35     </body>
36 </html>

 

  • 使用场景
    • 为不具备Iterator接口的对象提供遍历方法

4.ES6 async函数

  async函数时ES7才有的与异步操作有关的关键字,和Promise,Generator有很大的关联

  • async function name([param[,param[… param]]]){statements}
    • name:函数名称
    • param:要传递给函数的参数名称
    • statements:函数体语句
  • 返回值
    • async函数作为一个Promise对象,可以使用then方法添加回调函数
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             async function helloAsync(){
10                 return 'helloAsync';
11             }
12             console.log(helloAsync());
13             //Promise {<fulfilled>: 'helloAsync'}
14             helloAsync().then(v=>{
15                 console.log(v);
16             })
17             //helloAsync
18         </script>
19     </body>
20 </html>
    • async函数中可能会有await表达式,在async函数执行时如果遇到await就会先暂停执行,等到触发异步操作完成后,回复async函数的执行并返回解析值。注意:await关键字仅在async function函数体中有效。在此函数体外使用await,会报错:语法错误
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function testAwait(){
10                 return new Promise((resolve)=>{
11                     setTimeout(function(){
12                         console.log("testAwait");
13                         resolve();
14                     },1000);
15                 });
16             }
17             async function helloAsync(){
18                 await testAwait();
19                 console.log("helloAsync");
20             }
21             helloAsync();
22         </script>
23     </body>
24 </html>
  • await
    • await操作符用于等待一个Promise对象,它只能在异步函数async function中使用
    • [return_value] = await expression
      • expression:一个Promise对象或者任何要等的值
  • await针对所跟不同表达式的处理方式
    • Promise对象:await会暂停执行,等待Promise对象resolve,然后回复async函数的执行并返回解析值
    • 非Promise对象:执行返回对应值
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             async function a(){
10                 console.log(1);
11                 console.log(2);
12             }
13             a();
14             console.log(3);//1 2 3
15             async function b(){
16                 await 1;
17                 console.log(1);
18                 console.log(2);
19             }
20             b();
21             console.log(3);// 3 1 2
22         </script>
23     </body>
24 </html>
版权声明:本文为Miraitowa56原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Miraitowa-fan/p/16185149.html