一、概述

1、什么是 ECMA

先来个学习视频的网站:https://www.bilibili.com/video/BV1uK411H7on?p=2&spm_id_from=pageDriver ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际;

2、什么是 ECMAScript
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言;百度百科:https://baike.baidu.com/history/ECMAScript/1889420/144946978

3、什么是 ECMA-262
Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,所有标准列表查看:http://www.ecma-international.org/publications/standards/Standard.htm

4、ECMA-262 历史
ECMA-262(ECMAScript)历史版本查看网址:http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
image.png
5、谁在维护ECMA-262
TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席;

6、为什么要学习 ES6

ES6 的版本变动内容最多,具有里程碑意义;
ES6 加入许多新的语法特性,编程实现更简单、高效;
ES6 是前端发展趋势,就业必备技能;

7、ES6 兼容性

查看网址:http://kangax.github.io/compat-table/es6

二、ES6

let关键字

特性: let 关键字用来声明变量,使用 let 声明的变量有几个特点:

  1. 不允许重复声明;
  2. 块儿级作用域(局部变量);
  3. 不存在变量提升;
  4. 不影响作用域链;

let代码示例:

  1. // let关键字使用示例:
  2. let a; // 单个声明
  3. let b,c,d; // 批量声明
  4. let e = 100; // 单个声明并赋值
  5. let f = 521, g = 'iloveyou', h = []; // 批量声明并赋值
  6. // 1. 不允许重复声明;
  7. let dog = "狗";
  8. let dog = "狗";
  9. // 报错:Uncaught SyntaxError: Identifier 'dog' has already been declared
  10. // 2. 块儿级作用域(局部变量);
  11. {
  12. let cat = "猫";
  13. console.log(cat);
  14. }
  15. console.log(cat);
  16. // 报错:Uncaught ReferenceError: cat is not defined

什么是变量提升:

就是在变量创建之前使用(比如输出:输出的是默认值),let不存在,var存在;

  1. // 3. 不存在变量提升;
  2. // 什么是变量提升:就是在变量创建之前使用(比如输出:输出的是默认值),let不存 在,var存在;
  3. console.log(people1); // 可输出默认值
  4. console.log(people2); // 报错:Uncaught ReferenceError: people2 is not defined
  5. var people1 = "大哥"; // 存在变量提升
  6. let people2 = "二哥"; // 不存在变量提升

应用场景:以后声明变量使用 let 就对了;

const 关键字

特性:const 关键字用来声明常量,const 声明有以下特点:

  1. 声明必须赋初始值;
  2. 标识符一般为大写(习惯);
  3. 不允许重复声明;
  4. 值不允许修改;
  5. 块儿级作用域(局部变量);

const创建变量代码示例:

  1. <script>
  2. // const声明常量
  3. const DOG = "旺财";
  4. console.log(DOG);
  5. </script>
  6. // 1. 声明必须赋初始值;
  7. const CAT; //报错
  8. // 2. 不允许重复声明;
  9. const CAT = "喵喵";
  10. const CAT = "喵喵";
  11. // 3. 值不允许修改;
  12. // 注意:对数组元素的修改和对对象内部的修改是可以的(数组和对象存的是引用地址);
  13. const CAT = "喵喵";
  14. CAT = "咪咪";
  15. // 4. 块儿级作用域(局部变量);
  16. {
  17. const CAT = "喵喵";
  18. console.log(CAT);
  19. }
  20. console.log(CAT);

应用场景:声明对象类型使用 const,非对象类型声明选择 let; (留有疑问)

解构赋值

什么是解构赋值:

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值解构赋值的好处:相比数组和对象直接赋值是引用关系,利用结构赋值可以避免这种引用关系,实现深层克隆

代码演示及相关说明:
1、数组的解构赋值

  1. <script>
  2. const F4 = ["大哥","二哥","三哥","四哥"];
  3. // 1. 将数组解构出来
  4. let [a,b,c,d] = F4;
  5. console.log(a + b + c + d); // 大哥二哥三哥四哥
  6. // 2. 利用结构赋值添加新的元素
  7. let F5 = [...F4,"五哥"]
  8. console.log(F5) //['大哥', '二哥', '三哥', '四哥', '五哥']
  9. </script>

2、对象的解构赋值

  1. <script>
  2. // 1.解构对象中的数据
  3. const F3 = {
  4. name : "大哥",
  5. age : 22,
  6. sex : "男",
  7. xiaopin : function(){
  8. console.log("我会演小品!");
  9. }
  10. }
  11. let {name,age,sex,xiaopin} = F3; // 注意解构对象这里用的是{}
  12. console.log(name + age + sex + xiaopin); // 大哥22男
  13. xiaopin(); // 此方法可以正常调用
  14. // 1.1 如果想创建的变量名和对象的属性名不一致,可以这么写:
  15. const {a:a1} = obj;
  16. console.log(a1);// 1
  17. //1.2 补充 ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
  18. const {a,b,c,d,e} = obj || {};
  19. //2. 深层克隆;合并多个对象
  20. const F3 = {
  21. name : "大哥",
  22. age : 22,
  23. sex : "男",
  24. xiaopin : function(){
  25. console.log("我会演小品!");
  26. }
  27. }
  28. let F4 = { wife:'王五' }
  29. let F5 = {...F3,...F4}
  30. console.log(F5) // 输出 {name: '大哥', age: 22, sex: '男', wife: '王五', xiaopin: ƒ }
  31. F5.wife = '李四'
  32. console.log(F4.wife) //输出王五
  33. </script>

应用场景:频繁使用对象方法、数组元素,就可以使用解构赋值形式;

模板字符串

概述:
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:

  • 字符串中可以出现换行符;
  • 可以使用 ${xxx} ,在{ }中可以放入任意的javaScript表达式,可以进行运算,以及引用对象属性变量

代码演示及相关说明:

  1. <script>
  2. // 声明字符串的方法:单引号('')、双引号("")、反引号(``)
  3. // 声明
  4. let string = `我也一个字符串哦!`;
  5. console.log(string);
  6. // 特性
  7. // 1、字符串中可以出现换行符
  8. let str = `<ul>
  9. <li>大哥</li>
  10. <li>二哥</li>
  11. <li>三哥</li>
  12. <li>四哥</li>
  13. </ul>`;
  14. console.log(str);
  15. // 2、可以使用 ${xxx} 形式引用变量
  16. let s = "大哥";
  17. let out = `${s}是我最大的榜样!`;
  18. // 3.可以${xxx} 中写入任意js表达式
  19. const name = '小明';
  20. const score = 59;
  21. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
  22. // 4. 动态对象属性名
  23. // 原代码
  24. // let obj = {};
  25. // let index = 1;
  26. // let key = `topic${index}`;
  27. // obj[key] = '话题内容';
  28. //改进
  29. let obj = {};
  30. let index = 1;
  31. obj[`topic${index}`] = '话题内容';
  32. </script>

应用场景:当遇到字符串与变量拼接的情况使用模板字符串;

简化对象和函数写法

概述:
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;
代码示例及相关说明:

  1. <script>
  2. // ES6允许在对象的大括号内直接写入变量和函数作为对象的属性和方法
  3. // 变量和函数
  4. let name = "訾博";
  5. let change = function(){
  6. console.log("活着就是为了改变世界!");
  7. }
  8. //创建对象
  9. const school = {
  10. // 完整写法
  11. // name:name,
  12. // change:change
  13. // 简化写法
  14. name, //相当于 name:name
  15. change, //相当于 change:change
  16. // 声明方法的简化
  17. say(){
  18. console.log("言行一致!");
  19. }
  20. }
  21. school.change();
  22. school.say();
  23. </script>

箭头函数

概述:

ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义;

箭头函数的注意点:

  1. 如果形参只有一个,则小括号可以省略;
  2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果;
  3. 箭头函数 this 指向声明时所在作用域下 this 的值;
  4. 箭头函数不能作为构造函数实例化;
  5. 不能使用 arguments;

特性:

  1. 箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值;
  2. 不能作为构造实例化对象;
  3. 不能使用 arguments 变量;

代码演示及相关说明:

  1. 注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适;
  2. <script>
  3. // ES6允许使用箭头(=>)定义函数
  4. // 传统写法:无参数
  5. var say = function(){
  6. console.log("hello!");
  7. }
  8. say();
  9. // ES写法2:无参数
  10. let speak = () => console.log("hello 哈哈!");
  11. speak();
  12. // 传统写法:一个参数
  13. var hello = function(name){
  14. return "hello " + name;
  15. }
  16. console.log(hello("訾博"));
  17. // ES6箭头函数:一个参数
  18. let hi = name => "hi " + name;**运行结果:**
  19. console.log(hi("訾博"));
  20. // 传统写法:多个参数
  21. var sum = function(a,b,c){
  22. return a + b + c;
  23. }
  24. console.log(sum(1,2,3));
  25. // ES6箭头函数:多个参数
  26. let he = (a,b,c) => a + b + c;
  27. console.log(he(1,2,3));
  28. // 特性
  29. // 1、箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值
  30. const school = {
  31. name : "大哥",
  32. }
  33. // 传统函数
  34. function getName(){
  35. console.log("getName:" + this.name);
  36. }
  37. // 箭头函数
  38. getName1 = () => console.log("getName1:" + this.name);
  39. window.name = "訾博";
  40. // 直接调用
  41. getName();
  42. getName1();
  43. // 使用call调用
  44. getName.call(school);
  45. getName1.call(school);
  46. // 结论:箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值
  47. // 2、不能作为构造实例化对象
  48. // let Persion = (name,age) => {
  49. // this.name = name;
  50. // this.age = age;
  51. // }
  52. // let me = new Persion("訾博",24);
  53. // console.log(me);
  54. // 报错:Uncaught TypeError: Persion is not a constructor
  55. // 3、不能使用 arguments 变量
  56. // let fn = () => console.log(arguments);
  57. // fn(1,2,3);
  58. // 报错:Uncaught ReferenceError: arguments is not defined
  59. </script>

函数参数的默认值

概述:ES允许给函数的参数赋初始值;
代码示例及相关说明:

  1. <script>
  2. //ES6 允许给函数参数赋值初始值
  3. //1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
  4. function add(a,b,c=10) {
  5. return a + b + c;
  6. }
  7. let result = add(1,2);
  8. console.log(result); // 13
  9. //2. 与解构赋值结合
  10. // 注意这里参数是一个对象
  11. function connect({host="127.0.0.1", username,password, port}){
  12. console.log(host)
  13. console.log(username)
  14. console.log(password)
  15. console.log(port)
  16. }
  17. connect({
  18. host: 'atguigu.com',
  19. username: 'root',
  20. password: 'root',
  21. port: 3306
  22. })
  23. </script>

rest参数

概述:ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
参考文章:https://www.jianshu.com/p/50bcb376a419
代码示例及相关说明:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>rest参数</title>
  6. </head>
  7. <body>
  8. <script>
  9. // ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
  10. // ES5获取实参的方式
  11. function data(){
  12. console.log(arguments);
  13. }
  14. data("大哥","二哥","三哥","四哥");
  15. // ES6的rest参数...args,rest参数必须放在最后面
  16. function data(...args){
  17. console.log(args); // fliter some every map
  18. }
  19. data("大哥","二哥","三哥","四哥");
  20. </script>
  21. </body>
  22. </html>

扩展运算符

介绍:

  • … 扩展运算符能将数组转换为逗号分隔的参数序列;
  • 扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包;

基本使用:

  1. <script>
  2. // ... 扩展运算符能将数组转换为逗号分隔的参数序列
  3. //声明一个数组 ...
  4. const tfboys = ['易烊千玺', '王源', '王俊凯'];
  5. // => '易烊千玺','王源','王俊凯'
  6. // 声明一个函数
  7. function chunwan() {
  8. console.log(arguments);
  9. }
  10. chunwan(...tfboys); // chunwan('易烊千玺','王源','王俊凯')
  11. // 应用
  12. //1. 数组去重与合并(set和扩展运算符)
  13. const a = [1,2,3];
  14. const b = [1,5,6];
  15. const c = [...new Set([...a,...b])];//[1,2,3,5,6]
  16. const obj1 = {a:1,}
  17. const obj2 = {b:1,}
  18. const obj = {...obj1,...obj2};//{a:1,b:1}
  19. //2. 数组的克隆
  20. const sanzhihua = ['E','G','M'];
  21. const sanyecao = [...sanzhihua];// ['E','G','M']
  22. console.log(sanyecao);
  23. //3. 将伪数组转为真正的数组
  24. const divs = document.querySelectorAll('div');
  25. const divArr = [...divs];
  26. console.log(divArr);// arguments
  27. </script>

Symbol

Symbol概述:

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型; 参考文章:https://blog.csdn.net/fesfsefgs/article/details/108354248

Symbol 特点:

  1. Symbol 的值是唯一的,用来解决命名冲突的问题;
  2. Symbol 值不能与其他数据进行运算;
  3. Symbol 定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名;

基本使用:

  1. </script>
  2. //创建Symbol
  3. let s = Symbol();
  4. // console.log(s, typeof s);
  5. let s2 = Symbol('尚硅谷');**Symbol****创建对象属性:**
  6. let s3 = Symbol('尚硅谷');
  7. console.log(s2==s3); // false
  8. //Symbol.for 创建
  9. let s4 = Symbol.for('尚硅谷');
  10. let s5 = Symbol.for('尚硅谷');
  11. console.log(s4==s5); // true
  12. //不能与其他数据进行运算
  13. // let result = s + 100;
  14. // let result = s > 100;
  15. // let result = s + s;
  16. // USONB you are so niubility
  17. // u undefined
  18. // s string symbol
  19. // o object
  20. // n null number
  21. // b boolean
  22. </script>

Symbol实例 创建对象属性

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Symbol 创建对象属性</title>
  7. </head>
  8. <body>
  9. <script>
  10. //向对象中添加方法 up down
  11. let game = {
  12. name:'俄罗斯方块',
  13. up: function(){},
  14. down: function(){}
  15. };
  16. //声明一个对象
  17. // let methods = {
  18. // up: Symbol(),
  19. // down: Symbol()
  20. // };
  21. // game[methods.up] = function(){
  22. // console.log("我可以改变形状");
  23. // }
  24. // game[methods.down] = function(){
  25. // console.log("我可以快速下降!!");
  26. // }
  27. // console.log(game);
  28. //
  29. let youxi = {
  30. name:"狼人杀",
  31. [Symbol('say')]: function(){
  32. console.log("我可以发言")
  33. },
  34. [Symbol('zibao')]: function(){
  35. console.log('我可以自爆');
  36. }
  37. }
  38. console.log(youxi)
  39. </script>
  40. </body>
  41. </html>

Symbol内置值:

概述:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;
方法:
特别的: Symbol内置值的使用,都是作为某个对象类型的属性去使用
演示:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Symbol内置属性</title>
  7. </head>
  8. <body>
  9. <script>
  10. // class Person{
  11. // static [Symbol.hasInstance](param){
  12. // console.log(param);
  13. // console.log("我被用来检测类型了");
  14. // return false;
  15. // }
  16. // }
  17. // let o = {};
  18. // console.log(o instanceof Person);
  19. // const arr = [1,2,3];
  20. // const arr2 = [4,5,6];
  21. // arr2[Symbol.isConcatSpreadable] = false;
  22. // console.log(arr.concat(arr2));
  23. </script>
  24. </body>
  25. </html>

迭代器

概述:遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作;
特性:
ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费;
原生具备 iterator 接口的数据(可用 for of 遍历):

  • Array;
  • Arguments;
  • Set;
  • Map;
  • String;
  • TypedArray;
  • NodeList;

工作原理:

  1. 创建一个指针对象,指向当前数据结构的起始位置;
  2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
  3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
  4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;

注:需要自定义遍历数据的时候,要想到迭代器;
代码示例及相关说明:

  1. <script>
  2. // 声明一个数组
  3. const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];
  4. // 使用 for...of 遍历数组
  5. for(let v of xiyou){
  6. console.log(v);
  7. }
  8. let iterator = xiyou[Symbol.iterator]();
  9. // 调用对象的next方法
  10. console.log(iterator.next());
  11. console.log(iterator.next());
  12. console.log(iterator.next());
  13. console.log(iterator.next());
  14. console.log(iterator.next());
  15. // 重新初始化对象,指针也会重新回到最前面
  16. let iterator1 = xiyou[Symbol.iterator]();
  17. console.log(iterator1.next());
  18. </script>

迭代器自定义遍历对象:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>自定义遍历数据</title>
  7. </head>
  8. <body>
  9. <script>
  10. //声明一个对象
  11. const banji = {
  12. name: "终极一班",
  13. stus: [
  14. 'xiaoming',
  15. 'xiaoning',
  16. 'xiaotian',
  17. 'knight'
  18. ],
  19. [Symbol.iterator]() {
  20. //索引变量
  21. let index = 0;
  22. //
  23. let _this = this;
  24. return {
  25. next: function () {
  26. if (index < _this.stus.length) {
  27. const result = { value: _this.stus[index], done: false };
  28. //下标自增
  29. index++;
  30. //返回结果
  31. return result;
  32. }else{
  33. return {value: undefined, done: true};
  34. }
  35. }
  36. };
  37. }
  38. }
  39. //遍历这个对象
  40. for (let v of banji) {
  41. console.log(v);
  42. }
  43. </script>
  44. </body>
  45. </html>

生成器

概述:生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
基本使用:

  1. <script>
  2. // 生成器其实就是一个特殊的函数
  3. // 异步编程 纯回调函数 node fs ajax mongodb
  4. // yield:函数代码的分隔符
  5. function* gen() {
  6. console.log(111);
  7. yield '一只没有耳朵';
  8. console.log(222);
  9. yield '一只没有尾部';
  10. console.log(333);
  11. yield '真奇怪';
  12. console.log(444);
  13. }
  14. let iterator = gen();
  15. console.log(iterator.next());
  16. console.log(iterator.next());
  17. console.log(iterator.next());
  18. console.log(iterator.next());
  19. console.log("遍历:");
  20. //遍历
  21. for(let v of gen()){
  22. console.log(v);
  23. }
  24. </script>

生成器函数的参数传递:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>生成器函数参数</title>
  7. </head>
  8. <body>
  9. <script>
  10. function * gen(arg){
  11. console.log(arg);
  12. let one = yield 111;
  13. console.log(one);
  14. let two = yield 222;
  15. console.log(two);
  16. let three = yield 333;
  17. console.log(three);
  18. }
  19. //执行获取迭代器对象
  20. let iterator = gen('AAA');
  21. console.log(iterator.next());
  22. //next方法可以传入实参
  23. console.log(iterator.next('BBB'));
  24. console.log(iterator.next('CCC'));
  25. console.log(iterator.next('DDD'));
  26. </script>
  27. </body>
  28. </html>

生成器函数实例1:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>生成器函数实例</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 异步编程 文件操作 网络操作(ajax, request) 数据库操作
  11. // 1s 后控制台输出 111 2s后输出 222 3s后输出 333
  12. // 回调地狱
  13. // setTimeout(() => {
  14. // console.log(111);
  15. // setTimeout(() => {
  16. // console.log(222);
  17. // setTimeout(() => {
  18. // console.log(333);
  19. // }, 3000);
  20. // }, 2000);
  21. // }, 1000);
  22. function one(){
  23. setTimeout(()=>{
  24. console.log(111);
  25. iterator.next();
  26. },1000)
  27. }
  28. function two(){
  29. setTimeout(()=>{
  30. console.log(222);
  31. iterator.next();
  32. },2000)
  33. }
  34. function three(){
  35. setTimeout(()=>{
  36. console.log(333);
  37. iterator.next();
  38. },3000)
  39. }
  40. function * gen(){
  41. yield one();
  42. yield two();
  43. yield three();
  44. }
  45. //调用生成器函数
  46. let iterator = gen();
  47. iterator.next();
  48. </script>
  49. </body>
  50. </html>

生成器函数实例2:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>生成器函数</title>
  7. </head>
  8. <body>
  9. <script>
  10. //模拟获取 用户数据 订单数据 商品数据
  11. function getUsers(){
  12. setTimeout(()=>{
  13. let data = '用户数据';
  14. //调用 next 方法, 并且将数据传入
  15. iterator.next(data);
  16. }, 1000);
  17. }
  18. function getOrders(){
  19. setTimeout(()=>{
  20. let data = '订单数据';
  21. iterator.next(data);
  22. }, 1000)
  23. }
  24. function getGoods(){
  25. setTimeout(()=>{
  26. let data = '商品数据';
  27. iterator.next(data);
  28. }, 1000)
  29. }
  30. function * gen(){
  31. let users = yield getUsers();
  32. let orders = yield getOrders();
  33. let goods = yield getGoods();
  34. }
  35. //调用生成器函数
  36. let iterator = gen();
  37. iterator.next();
  38. </script>
  39. </body>
  40. </html>

运行结果:
image.png

Promise

概述:Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果;

  1. Promise 构造函数: Promise (excutor) {};
  2. Promise.prototype.then 方法;
  3. Promise.prototype.catch 方法;

基本使用:

  1. <script>
  2. // 实例化 Promise 对象
  3. // Promise 对象三种状态:初始化、成功、失败
  4. const p = new Promise(function(resolve,reject){
  5. setTimeout(function(){
  6. // 成功
  7. // let data = "数据";
  8. // 调用resolve,这个Promise 对象的状态就会变成成功
  9. // resolve(data);
  10. // 失败
  11. let err = "失败了!";
  12. reject(err);
  13. },1000);
  14. });
  15. // 成功
  16. // 调用 Promise 对象的then方法,两个参数为函数
  17. p.then(function(value){ // 成功
  18. console.log(value);
  19. }, function(season){ // 失败
  20. console.log(season);
  21. });
  22. </script>

Promise封装读取文件:

一般写法:

  1. // 1、引入 fs 模块
  2. const fs = require("fs");
  3. // 2、调用方法,读取文件
  4. fs.readFile("resources/text.txt",(err,data)=>{
  5. // 如果失败则抛出错误
  6. if(err) throw err;
  7. // 如果没有出错,则输出内容
  8. console.log(data.toString());
  9. });

Promise封装:

  1. //1. 引入 fs 模块
  2. const fs = require('fs');
  3. //2. 调用方法读取文件
  4. // fs.readFile('./resources/为学.md', (err, data)=>{
  5. // //如果失败, 则抛出错误
  6. // if(err) throw err;
  7. // //如果没有出错, 则输出内容
  8. // console.log(data.toString());
  9. // });
  10. //3. 使用 Promise 封装
  11. const p = new Promise(function(resolve, reject){
  12. fs.readFile("./resources/为学.mda", (err, data)=>{
  13. //判断如果失败
  14. if(err) reject(err);
  15. //如果成功
  16. resolve(data);
  17. });
  18. });
  19. p.then(function(value){
  20. console.log(value.toString());
  21. }, function(reason){
  22. console.log("读取失败!!");
  23. });

运行结果:
image.png

Promise封装Ajax请求:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>发送 AJAX 请求</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 接口地址: https://api.apiopen.top/getJoke
  11. const p = new Promise((resolve, reject) => {
  12. //1. 创建对象
  13. const xhr = new XMLHttpRequest();
  14. //2. 初始化
  15. xhr.open("GET", "https://api.apiopen.top/getJ");
  16. //3. 发送
  17. xhr.send();
  18. //4. 绑定事件, 处理响应结果
  19. xhr.onreadystatechange = function () {
  20. //判断
  21. if (xhr.readyState === 4) {
  22. //判断响应状态码 200-299
  23. if (xhr.status >= 200 && xhr.status < 300) {
  24. //表示成功
  25. resolve(xhr.response);
  26. } else {
  27. //如果失败
  28. reject(xhr.status);
  29. }
  30. }
  31. }
  32. })
  33. //指定回调
  34. p.then(function(value){
  35. console.log(value);
  36. }, function(reason){
  37. console.error(reason);
  38. });
  39. </script>
  40. </body>
  41. </html>

运行结果:
image.png

Promise-then方法

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Promise.prototype.then</title>
  7. </head>
  8. <body>
  9. <script>
  10. //创建 promise 对象
  11. const p = new Promise((resolve, reject)=>{
  12. setTimeout(()=>{
  13. resolve('用户数据');
  14. // reject('出错啦');
  15. }, 1000)
  16. });
  17. //调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
  18. //1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
  19. // const result = p.then(value => {
  20. // console.log(value);
  21. // //1. 非 promise 类型的属性
  22. // // return 'iloveyou';
  23. // //2. 是 promise 对象
  24. // // return new Promise((resolve, reject)=>{
  25. // // // resolve('ok');
  26. // // reject('error');
  27. // // });
  28. // //3. 抛出错误
  29. // // throw new Error('出错啦!');
  30. // throw '出错啦!';
  31. // }, reason=>{
  32. // console.warn(reason);
  33. // });
  34. //链式调用
  35. p.then(value=>{
  36. }).then(value=>{
  37. });
  38. </script>
  39. </body>
  40. </html>

运行结果:
image.png

Promise-catch方法

catch是promise函数失败的回调函数,是一个语法糖,相当于then方法的第二个参数

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>catch方法</title>
  7. </head>
  8. <body>
  9. <script>
  10. const p = new Promise((resolve, reject)=>{
  11. setTimeout(()=>{
  12. //设置 p 对象的状态为失败, 并设置失败的值
  13. reject("出错啦!");
  14. }, 1000)
  15. });
  16. // p.then(function(value){}, function(reason){
  17. // console.error(reason);
  18. // });
  19. p.catch(function(reason){
  20. console.warn(reason);
  21. });
  22. </script>
  23. </body>
  24. </html>

Promise实践练习 - “回调地狱”方式写法:

  1. //引入 fs 模块
  2. const fs = require("fs");
  3. fs.readFile('./resources/为学.md', (err, data1)=>{
  4. fs.readFile('./resources/插秧诗.md', (err, data2)=>{
  5. fs.readFile('./resources/观书有感.md', (err, data3)=>{
  6. let result = data1 + '\r\n' +data2 +'\r\n'+ data3;
  7. console.log(result);
  8. });
  9. });
  10. });

Promise实践练习 - “回调地狱”改良:

  1. //引入 fs 模块
  2. const fs = require("fs");
  3. //使用 promise 实现
  4. const p = new Promise((resolve, reject) => {
  5. fs.readFile("./resources/为学.md", (err, data) => {
  6. resolve(data);
  7. });
  8. });
  9. p.then(value => {
  10. return new Promise((resolve, reject) => {
  11. fs.readFile("./resources/插秧诗.md", (err, data) => {
  12. resolve([value, data]);
  13. });
  14. });
  15. }).then(value => {
  16. return new Promise((resolve, reject) => {
  17. fs.readFile("./resources/观书有感.md", (err, data) => {
  18. //压入
  19. value.push(data);
  20. resolve(value);
  21. });
  22. })
  23. }).then(value => {
  24. console.log(value.join('\r\n'));
  25. });

set集合

概述:
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:

  1. size 返回集合的元素个数;
  2. add 增加一个新元素,返回当前集合;
  3. delete 删除元素,返回 boolean 值;
  4. has 检测集合中是否包含某个元素,返回 boolean 值;
  5. clear 清空集合,返回 undefined;

基本使用:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>集合</title>
  7. </head>
  8. <body>
  9. <script>
  10. let s = new Set();
  11. console.log(s,typeof s);
  12. let s1 = new Set(["大哥","二哥","三哥","四哥","三哥"]);
  13. console.log(s1); // 自动去重
  14. // 1. size 返回集合的元素个数;
  15. console.log(s1.size);
  16. // 2. add 增加一个新元素,返回当前集合;
  17. s1.add("大姐");
  18. console.log(s1);
  19. // 3. delete 删除元素,返回 boolean 值;
  20. let result = s1.delete("三哥");
  21. console.log(result);
  22. console.log(s1);
  23. // 4. has 检测集合中是否包含某个元素,返回 boolean 值;
  24. let r1 = s1.has("二姐");
  25. console.log(r1);
  26. // 5. clear 清空集合,返回 undefined;
  27. s1.clear();
  28. console.log(s1);
  29. </script>
  30. </body>
  31. </html>

Set集合实践:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Set 实践</title>
  7. </head>
  8. <body>
  9. <script>
  10. let arr = [1,2,3,4,5,4,3,2,1];
  11. //1. 数组去重与合并(set和扩展运算符)
  12. const a = [1,2,3];
  13. const b = [1,5,6];
  14. const c = [...new Set([...a,...b])];//[1,2,3,5,6]
  15. const obj1 = {a:1,}
  16. const obj2 = {b:1,}
  17. const obj = {...obj1,...obj2};//{a:1,b:1}
  18. console.log(result);
  19. //2. 交集
  20. let arr2 = [4,5,6,5,6];
  21. // let result = [...new Set(arr)].filter(item => {
  22. // let s2 = new Set(arr2);// 4 5 6
  23. // if(s2.has(item)){
  24. // return true;
  25. // }else{
  26. // return false;
  27. // }
  28. // });
  29. // let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
  30. // console.log(result);
  31. //3. 并集
  32. // let union = [...new Set([...arr, ...arr2])];
  33. // console.log(union);
  34. //4. 差集
  35. let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
  36. console.log(diff);
  37. </script>
  38. </body>
  39. </html>

map集合

概述:
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历;
Map 的属性和方法:

  1. size 返回 Map 的元素个数;
  2. set 增加一个新元素,返回当前 Map;
  3. get 返回键名对象的键值;
  4. has 检测 Map 中是否包含某个元素,返回 boolean 值;
  5. clear 清空集合,返回 undefined;

基础使用:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Map</title>
  7. </head>
  8. <body>
  9. <script>
  10. //声明 Map
  11. let m = new Map();
  12. //添加元素
  13. m.set('name','尚硅谷');
  14. m.set('change', function(){
  15. console.log("我们可以改变你!!");
  16. });
  17. let key = {
  18. school : 'ATGUIGU'
  19. };
  20. m.set(key, ['北京','上海','深圳']);
  21. //size
  22. // console.log(m.size);
  23. //删除
  24. // m.delete('name');
  25. //获取
  26. // console.log(m.get('change'));
  27. // console.log(m.get(key));
  28. //清空
  29. // m.clear();
  30. //遍历
  31. for(let v of m){
  32. console.log(v);
  33. }
  34. // console.log(m);
  35. </script>
  36. </body>
  37. </html>

calss类

概述:
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;
知识点:

  1. class 声明类;
  2. constructor 定义构造函数初始化;
  3. extends 继承父类;
  4. super 调用父级构造方法;
  5. static 定义静态方法和属性;
  6. 父类方法可以重写;

class初体验:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>类声明</title>
  7. </head>
  8. <body>
  9. <script>
  10. //手机
  11. function Phone(brand, price){
  12. this.brand = brand;
  13. this.price = price;
  14. }
  15. //添加方法
  16. Phone.prototype.call = function(){
  17. console.log("我可以打电话!!");
  18. }
  19. //实例化对象
  20. let Huawei = new Phone('华为', 5999);
  21. Huawei.call();
  22. console.log(Huawei);
  23. //class
  24. class Shouji{
  25. //构造方法 名字不能修改
  26. constructor(brand, price){
  27. this.brand = brand;
  28. this.price = price;
  29. }
  30. //方法必须使用该语法, 不能使用 ES5 的对象完整形式
  31. call(){
  32. console.log("我可以打电话!!");
  33. }
  34. }
  35. let onePlus = new Shouji("1+", 1999);
  36. console.log(onePlus);
  37. </script>
  38. </body>
  39. </html>

class静态成员

静态方法:类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
静态属性:静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。ES6使用静态属性和实例属性:
代码实现:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>静态成员</title>
  7. </head>
  8. <body>
  9. <script>
  10. // function Phone(){
  11. // }
  12. // Phone.name = '手机';
  13. // Phone.change = function(){
  14. // console.log("我可以改变世界");
  15. // }
  16. // Phone.prototype.size = '5.5inch';
  17. // let nokia = new Phone();
  18. // console.log(nokia.name);
  19. // // nokia.change();
  20. // console.log(nokia.size);
  21. class Phone{
  22. //静态属性
  23. static name = '手机';
  24. static change(){
  25. console.log("我可以改变世界");
  26. }
  27. }
  28. let nokia = new Phone();
  29. console.log(nokia.name);
  30. console.log(Phone.name);
  31. </script>
  32. </body>
  33. </html>

运行结果:
image.png

ES5构造函数实现继承:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>对象继承</title>
  7. </head>
  8. <body>
  9. <script>
  10. //手机
  11. function Phone(brand, price){
  12. this.brand = brand;
  13. this.price = price;
  14. }
  15. Phone.prototype.call = function(){
  16. console.log("我可以打电话");
  17. }
  18. //智能手机
  19. function SmartPhone(brand, price, color, size){
  20. Phone.call(this, brand, price);
  21. this.color = color;
  22. this.size = size;
  23. }
  24. //设置子级构造函数的原型
  25. SmartPhone.prototype = new Phone;
  26. SmartPhone.prototype.constructor = SmartPhone;
  27. //声明子类的方法
  28. SmartPhone.prototype.photo = function(){
  29. console.log("我可以拍照")
  30. }
  31. SmartPhone.prototype.playGame = function(){
  32. console.log("我可以玩游戏");
  33. }
  34. const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');
  35. console.log(chuizi);
  36. </script>
  37. </body>
  38. </html>

ES6class类继承:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>类继承-2</title>
  7. </head>
  8. <body>
  9. <script>
  10. class Phone{
  11. //构造方法
  12. constructor(brand, price){
  13. this.brand = brand;
  14. this.price = price;
  15. }
  16. //父类的成员属性
  17. call(){
  18. console.log("我可以打电话!!");
  19. }
  20. }
  21. class SmartPhone extends Phone {
  22. //构造方法
  23. constructor(brand, price, color, size){
  24. super(brand, price);// Phone.call(this, brand, price)
  25. this.color = color;
  26. this.size = size;
  27. }
  28. photo(){
  29. console.log("拍照");
  30. }
  31. playGame(){
  32. console.log("玩游戏");
  33. }
  34. call(){
  35. console.log('我可以进行视频通话');
  36. }
  37. }
  38. const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
  39. // console.log(xiaomi);
  40. xiaomi.call();
  41. xiaomi.photo();
  42. xiaomi.playGame();
  43. </script>
  44. </body>
  45. </html>

子类对父类方法重写:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>ES6class类继承</title>
  6. </head>
  7. <body>
  8. <script>
  9. // ES6class类继承
  10. class Phone{
  11. constructor(brand,price) {
  12. this.brand = brand;
  13. this.price = price;
  14. }
  15. call(){
  16. console.log("我可以打电话!");
  17. }
  18. }
  19. class SmartPhone extends Phone{
  20. // 构造函数
  21. constructor(brand,price,color,size) {
  22. super(brand,price); // 调用父类构造函数
  23. this.color = color;
  24. this.size = size;
  25. }
  26. // 子类对父类方法重写
  27. // 直接写,直接覆盖
  28. // 注意:子类无法调用父类同名方法
  29. call(){
  30. console.log("我可以进行视频通话!");
  31. }
  32. photo(){
  33. console.log("我可以拍照!");
  34. }
  35. game(){
  36. console.log("我可以玩游戏!");
  37. }
  38. }
  39. const chuizi = new SmartPhone("小米",1999,"黑色","5.15inch");
  40. console.log(chuizi);
  41. chuizi.call();
  42. chuizi.photo();
  43. chuizi.game();
  44. </script>
  45. </body>
  46. </html>

class中的 get | set

代码实现:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>get set</title>
  7. </head>
  8. <body>
  9. <script>
  10. // get 和 set
  11. class Phone{
  12. get price(){
  13. console.log("价格属性被读取了");
  14. return 'iloveyou';
  15. }
  16. set price(newVal){
  17. console.log('价格属性被修改了');
  18. }
  19. }
  20. //实例化对象
  21. let s = new Phone();
  22. // console.log(s.price);
  23. s.price = 'free';
  24. </script>
  25. </body>
  26. </html>

运行结果:
image.png

数值扩展

1. Number.EPSILON:

Number.EPSILON 是 JavaScript 表示的最小精度; EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;

2. 二进制和八进制:

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;

3. Number.isFinite() Number.isNaN()

Number.isFinite() 用来检查一个数值是否为有限的; Number.isNaN() 用来检查一个值是否为 NaN;

4. Number.parseInt() 与 Number.parseFloat():

ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;

5. Math.trunc

用于去除一个数的小数部分,返回整数部分;

6. Number.isInteger:

Number.isInteger() 用来判断一个数值是否为整数;

7. Math.sign

判断一个数到底为正数 负数 还是零

代码实现和相关说明:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>数值扩展</title>
  7. </head>
  8. <body>
  9. <script>
  10. //0. Number.EPSILON 是 JavaScript 表示的最小精度
  11. //EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
  12. // function equal(a, b){
  13. // if(Math.abs(a-b) < Number.EPSILON){
  14. // return true;
  15. // }else{
  16. // return false;
  17. // }
  18. // }
  19. // console.log(0.1 + 0.2 === 0.3);
  20. // console.log(equal(0.1 + 0.2, 0.3))
  21. //1. 二进制和八进制
  22. // let b = 0b1010;
  23. // let o = 0o777;
  24. // let d = 100;
  25. // let x = 0xff;
  26. // console.log(x);
  27. //2. Number.isFinite 检测一个数值是否为有限数
  28. // console.log(Number.isFinite(100));
  29. // console.log(Number.isFinite(100/0));
  30. // console.log(Number.isFinite(Infinity));
  31. //3. Number.isNaN 检测一个数值是否为 NaN
  32. // console.log(Number.isNaN(123));
  33. //4. Number.parseInt Number.parseFloat字符串转整数
  34. // console.log(Number.parseInt('5211314love'));
  35. // console.log(Number.parseFloat('3.1415926神奇'));
  36. //5. Number.isInteger 判断一个数是否为整数
  37. // console.log(Number.isInteger(5));
  38. // console.log(Number.isInteger(2.5));
  39. //6. Math.trunc 将数字的小数部分抹掉
  40. // console.log(Math.trunc(3.5));
  41. //7. Math.sign 判断一个数到底为正数 负数 还是零
  42. console.log(Math.sign(100));
  43. console.log(Math.sign(0));
  44. console.log(Math.sign(-20000));
  45. </script>
  46. </body>
  47. </html>

对象方法扩展

概述:
ES6 新增了一些 Object 对象的方法:

  1. Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);
  2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;
  3. proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;

代码实现及相关说明:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>对象方法扩展</title>
  7. </head>
  8. <body>
  9. <script>
  10. //1. Object.is 判断两个值是否完全相等
  11. // console.log(Object.is(120, 120));// ===
  12. // console.log(Object.is(NaN, NaN));// ===
  13. // console.log(NaN === NaN);// ===
  14. //2. Object.assign 对象的合并
  15. // const config1 = {
  16. // host: 'localhost',
  17. // port: 3306,
  18. // name: 'root',
  19. // pass: 'root',
  20. // test: 'test'
  21. // };
  22. // const config2 = {
  23. // host: 'http://atguigu.com',
  24. // port: 33060,
  25. // name: 'atguigu.com',
  26. // pass: 'iloveyou',
  27. // test2: 'test2'
  28. // }
  29. // console.log(Object.assign(config1, config2));
  30. //3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
  31. const school = {
  32. name: '尚硅谷'
  33. }
  34. const cities = {
  35. xiaoqu: ['北京','上海','深圳']
  36. }
  37. Object.setPrototypeOf(school, cities);
  38. console.log(Object.getPrototypeOf(school));
  39. console.log(school);
  40. </script>
  41. </body>
  42. </html>

运行结果:待补充

模块化

概述:模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;
模块化的好处:

模块化的优势有以下几点:

  1. 防止命名冲突;
  2. 代码复用;
  3. 高维护性;

模块化规范产品:

ES6 之前的模块化规范有:

  1. CommonJS => NodeJS、Browserify;
  2. AMD => requireJS;
  3. CMD => seaJS;

ES6 模块化语法:

  1. 模块功能主要由两个命令构成:export 和 import;
  2. export 命令用于规定模块的对外接口(导出模块);
  3. import 命令用于输入其他模块提供的功能(导入模块);

模块导出 | 模块暴露:

  1. // 1.分别暴露 - export关键字
  2. export let school = '尚硅谷';
  3. export function teach() {
  4. console.log("我们可以教给你开发技能");
  5. }
  6. // 2.统一暴露
  7. let school = '尚硅谷';
  8. function findJob(){
  9. console.log("我们可以帮助你找工作!!");
  10. }
  11. // 统一暴露的语法在这里
  12. export {school, findJob};
  13. //3.默认暴露 - default关键字
  14. export default {
  15. school: 'ATGUIGU',
  16. change: function(){
  17. console.log("我们可以改变你!!");
  18. }
  19. }

模块引入 | 使用模块:

  1. //入口文件 -> app.js
  2. //模块引入
  3. import * as m1 from "./m1.js";
  4. import * as m2 from "./m2.js";
  5. import * as m3 from "./m3.js";
  6. console.log(m1);
  7. console.log(m2);
  8. console.log(m3);
  9. m1.teach();
  10. m2.findJob();
  11. m3.default.change();

运行结果:
image.png

ES6导入模块语法汇总:

模块化.html:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>模块化</title>
  6. </head>
  7. <body>
  8. <script type="module">
  9. // 通用方式
  10. // 引入m.js模块内容
  11. import * as m from "./js/m.js";
  12. console.log(m);
  13. console.log(m.school);
  14. m.teach();
  15. // 引入n.js模块内容
  16. import * as n from "./js/n.js";
  17. console.log(n);
  18. console.log(n.school);
  19. n.findJob();
  20. // 引入o.js模块内容
  21. import * as o from "./js/o.js";
  22. console.log(o);
  23. // 注意这里调用方法的时候需要加上default
  24. console.log(o.default.school);
  25. o.default.change();
  26. // 解构赋值形式
  27. import {school,teach} from "./js/m.js";
  28. // 重名的可以使用别名
  29. import {school as xuexiao,findJob} from "./js/n.js";
  30. // 导入默认导出的模块,必须使用别名
  31. import {default as one} from "./js/o.js";
  32. // 直接可以使用
  33. console.log(school);
  34. teach();
  35. console.log(xuexiao);
  36. console.log(one);
  37. console.log(one.school);
  38. one.change();
  39. // 简便形式,只支持默认导出
  40. import oh from "./js/o.js";
  41. console.log(oh);
  42. console.log(oh.school);
  43. oh.change();
  44. </script>
  45. </body>
  46. </html>

ES7新特性

1、includes

判断数组中是否包含某元素,语法:arr.includes(元素值);

概述:

Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值; 判断数组中是否包含某元素,语法:arr.includes(元素值);

代码实现:

  1. <script>
  2. // 老式写法 => 关于if中判断条件
  3. if( type == 1 || type == 2 || type == 3 || type == 4 || ){
  4. //...
  5. }
  6. // includes 妙用
  7. const condition = [1,2,3,4];
  8. if( condition.includes(type) ){
  9. //...
  10. }
  11. </script>

2、指数操作

  1. 幂运算的简化写法,例如:210次方:2**10

概述:

  1. ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同;幂运算的简化写法,例如:210次方:2**10

代码实现:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>指数操作符</title>
  6. </head>
  7. <body>
  8. <script>
  9. // 指数操作符
  10. console.log(Math.pow(2,10))
  11. console.log(2**10);
  12. </script>
  13. </body>
  14. </html>

运行结果:

ES8新特性

1、async 和 await

概述:

async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;简化异步函数的写法,实现代码的扁平化;

async函数:

概述:

  1. async 函数的返回值为 promise 对象;
  2. promise 对象的结果由 async 函数执行的返回值决定;

代码实现:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>async函数</title>
  6. </head>
  7. <body>
  8. <script>
  9. // async函数:异步函数
  10. async function fn(){
  11. // return 123; // 返回普通数据
  12. // 若报错,则返回的Promise对象也是错误的
  13. // throw new Error("出错啦!");
  14. // 若返回的是Promise对象,那么返回的结果就是Promise对象的结果
  15. return new Promise((resolve,reject)=>{
  16. // resolve("成功啦!");
  17. reject("失败啦!");
  18. })
  19. }
  20. const result = fn();
  21. // console.log(result); // 返回的结果是一个Promise对象
  22. // 调用then方法
  23. result.then(value => {
  24. console.log(value);
  25. },reason => {
  26. console.warn(reason);
  27. });
  28. </script>
  29. </body>
  30. </html>

await表达式:

概述:

  1. await 必须写在 async 函数中;
  2. await 右侧的表达式一般为 promise 对象;
  3. await 返回的是 promise 成功的值;
  4. await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理; 备注: promise如果返回 reject 需要用try catch 来捕获错误
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>await表达式</title>
  6. </head>
  7. <body>
  8. <script>
  9. // async函数 + await表达式:异步函数
  10. // 创建Prmise对象
  11. const p = new Promise((resolve,reject)=>{
  12. resolve("成功啦!");
  13. })
  14. async function fn(){
  15. // await 返回的是 promise 成功的值
  16. let result = await p;
  17. console.log(result); // 成功啦!
  18. }
  19. fn();
  20. </script>
  21. </body>
  22. </html>

async 和 await 读取文件案例:

代码实现:

  1. / 导入模块
  2. const fs = require("fs");
  3. // 读取
  4. function readText() {
  5. return new Promise((resolve, reject) => {
  6. fs.readFile("../resources/text.txt", (err, data) => {
  7. //如果失败
  8. if (err) reject(err);
  9. //如果成功
  10. resolve(data);
  11. })
  12. })
  13. }
  14. function readTest1() {
  15. return new Promise((resolve, reject) => {
  16. fs.readFile("../resources/test1.txt", (err, data) => {
  17. //如果失败
  18. if (err) reject(err);
  19. //如果成功
  20. resolve(data);
  21. })
  22. })
  23. }
  24. function readTest2() {
  25. return new Promise((resolve, reject) => {
  26. fs.readFile("../resources/test2.txt", (err, data) => {
  27. //如果失败
  28. if (err) reject(err);
  29. //如果成功
  30. resolve(data);
  31. })
  32. })
  33. }
  34. //声明一个 async 函数
  35. async function main(){
  36. //获取为学内容
  37. let t0 = awai readText();
  38. //获取插秧诗内容
  39. let t1 = await readTest1();
  40. // 获取观书有感
  41. let t2 = await readTest2();
  42. console.log(t0.toString());
  43. console.log(t1.toString());
  44. console.log(t2.toString());
  45. }
  46. main();

async 和 await 结合发送ajax请求:

代码实现:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>async await 结合发送ajax请求</title>
  6. </head>
  7. <body>
  8. <script>
  9. // async 和 await 结合发送ajax请求
  10. function sendAjax(url){
  11. return new Promise((resolve,reject)=>{
  12. // 1、创建对象
  13. const x = new XMLHttpRequest();
  14. // 2、初始化
  15. x.open("GET",url);
  16. // 3、发送
  17. x.send();
  18. // 4、事件绑定
  19. x.onreadystatechange = function(){
  20. if(x.readyState == 4){
  21. if(x.status>=200 && x.status<=299){
  22. // 成功
  23. resolve(x.response);
  24. }else{
  25. // 失败
  26. reject(x.status);
  27. }
  28. }
  29. }
  30. });
  31. }
  32. // 测试
  33. // const result = sendAjax("https://api.apiopen.top/getJoke");
  34. // result.then(value=>{
  35. // console.log(value);
  36. // },reason=>{
  37. // console.warn(reason);
  38. // })
  39. // 使用async和await
  40. async function main(){
  41. let result = await sendAjax("https://api.apiopen.top/getJoke");
  42. console.log(result);
  43. }
  44. main();
  45. </script>
  46. </body>
  47. </html>

2、对象方法扩展

Object.values、Object.entries和Object.getOwnPropertyDescriptors:

  1. Object.values()方法:返回一个给定对象的所有可枚举属性值的数组;
  2. Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组;
  3. Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;

代码实现:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>对象方法扩展</title>
  6. </head>
  7. <body>
  8. <script>
  9. // 对象方法扩展
  10. let school = {
  11. name : "訾博",
  12. age : 24,
  13. sex : "男"
  14. }
  15. // 获取对象所有的键
  16. console.log(Object.keys(school));
  17. // 获取对象所有的值
  18. console.log(Object.values(school));
  19. // 获取对象的entries
  20. console.log(Object.entries(school));
  21. // 创建map
  22. const map = new Map(Object.entries(school));
  23. console.log(map);
  24. console.log(map.get("name"));
  25. // 返回指定对象所有自身属性的描述对象
  26. console.log(Object.getOwnPropertyDescriptors(school));
  27. // 参考内容:
  28. const obj = Object.create(null,{
  29. name : {
  30. // 设置值
  31. value : "訾博",
  32. // 属性特性
  33. writable : true,
  34. configuration : true,
  35. enumerable : true
  36. }
  37. });
  38. </script>
  39. </body>
  40. </html>