ES6 特性全面解析与应用实践

1、let

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

  1. 不允许重复声明

  2. 块儿级作用域

  3. 不存在变量提升

  4. 不影响作用域链

  5. 暂时性死区

6)不与顶级对象挂钩

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为"暂时性死区"。该变量在声明之前使用都属于"暂时性死区"。

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

javascript 复制代码
  <script>
      //声明变量格式
      let a;
      let b, c, d;
      let e = 100;
      let f = 521,
        g = "iloveyou",
        h = [];


      //1. 变量不能重复声明,防止变量被污染
      // let star = '王老师';
      // let star = '余老师';  //会报错


      //2. 块儿级作用域  避免暴露成全程作用域,影响别人
     {
          let girl = '王老师';
          var boy='张老师'
      }
      console.log(girl);//报错
      console.log(boy);//张老师
      
      // if  else  while  for  这些语句里,都是有块级作用域的
       //for 循环的计算器,就很合适let命令
      for(let i=0;i<3;i++){
        console.log(i);//0,1,2
      }
      console.log(i);//报错


      //3. 不影响作用域链
      //作用域链:内层作用域 ------> 外层作用域 ------> 全局作用域
      {
        let school = "bdqn";
        function fn() {
          console.log(school);//在fn作用域没有,还是会向上寻找
        }
        fn();
      }


      //4. 不存在变量提升
      // console.log(song);
      // let song = '恋爱达人';
      
        // 5、let暂时性死区
      var a = 1;
      if (true) {
        a = 2; // 报错,初始化前不能访问a,也就是在同一个作用域中,不可以访问,再定义
        let a = 1;
      }
      
       // 6、 不与顶层对象挂钩
      var myname='zhangsan'
      let myage=18
      console.log(window.myname);//zhangsan
      console.log(window.myage);//undefined
      
    </script>

2、const

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

  1. 声明必须赋初始值

  2. 标识符一般为大写(建议)

  3. 不允许重复声明

  4. 值不允许修改

const实际上保存的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。

注意 : 对象属性修改和数组元素变化不会出发 const 错误, 对象地址不可改变。

  1. 块儿级作用域

6)、 不与顶层对象挂钩

应用场景:声明对象类型使用const,非对象类型声明选择let

javascript 复制代码
 <script>
        //声明常量
        const SCHOOL = 'bdqn';
        //注意事项
        //1. 一定要赋初始值
        // const A;
        //2. 一般常量使用大写(潜规则)
        // const a = 100;
        //3. 常量的值不能修改
        // SCHOOL = 'bdqn';
        //4. 块儿级作用域
        // {
        //     const PLAYER = 'UZI';
        // }
        // console.log(PLAYER);
        //5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
        const TEAM = ['UZI','MXLG','Ming','Letme'];
        // TEAM.push('Meiko');
          // 6、 不与顶层对象挂钩
      var myname = "zhangsan";
      const myage = 18;
      console.log(window.myname); //zhangsan
      console.log(window.myage); //undefined
    </script>

面试题1.let和const的区别(/var,let,const的区别?)

let声明的变量可以改变,值和类型都可以改变(let:声明的是变量);

const声明的常量不可以改变,这意味着,const一旦声明,就必须立即初始化,不能以后再赋值,当然数组和对象等复合类型的变量,变量名不指向数据,而是指向数据所在的地址。

const只保证变量名指向的地址不变,并不保证该地址的数据不变。

let const 总结

let 声明的变量会产生块作用域,var 不会产生块作用域

const 声明的常量也会产生块作用域

不同代码块之间的变量无法互相访问

注意: 对象属性修改和数组元素变化不会出发 const 错误 (数组和对象存的是引用地址)

应用场景:声明对象类型使用 const,非对象类型声明选择 let

cosnt声明必须赋初始值,标识符一般为大写,值不允许修改。

3、变量的解构赋值

ES6 允许按照一定模式,从数组和对象中快速的提取成员,对变量进行赋值,这被称为解构赋值。

本质上,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

1>解构分类

(1)、数组的解构

ES6中允许从数组中提取值,按照对应位置,对变量赋值

javascript 复制代码
<script>
        //数组的解构
        const F4 = ['小沈阳','刘能','赵四','宋小宝'];
        let [xiao, liu, zhao, song] = F4;
        console.log(xiao);
        console.log(liu);
        console.log(zhao);
        console.log(song); 
        // 省略变量
        let [a, , c] = [1, 2, 3]; 
      console.log(a, c);//1,3
</script>
(2)、对象的解构

对象的解构与数组有一个重要的不同。数组的元素是按顺序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值,否则解构失败就是undefined。

vb 复制代码
`<script>
        //对象的解构
     const zhao = {
        name: "赵本山",
        age: "不详",
        xiaopin: function () {
          console.log("我可以演小品");
        },
        data: {
          list: ["贾玲", "沈腾", "···"],
        },
      };

      let {
        name:n,//起别名
        age=18,//可以定义默认值
        xiaopin,
        data: { list },//可以解构下一级数据
      } = zhao;
      console.log(n);//赵本山
      console.log(age);
      console.log(xiaopin);
      console.log(list);
      xiaopin();
        
        let {xiaopin} = zhao;
        xiaopin();
    </script>`
(3)、字符串解构
javascript 复制代码
let [a, b, c] = "hello";
      console.log(a); //h
      console.log(b); //e
      console.log(c); //l
 let { length } = "hello";
      console.log(length);//5

2、解构应用

(1)、变量值交换
javascript 复制代码
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a);
(2)、函数返回多个值
javascript 复制代码
 function myfun() {
          return [2, 3, 4];
        }
        let [a, b, c] = myfun();
        console.log([a, b, c]);//[2, 3, 4]
        console.log(a);//2
        console.log(b);//3
        console.log(c);//4
(3)、函数参数传参数
javascript 复制代码
 function myfun([a, b, c]) {
        console.log(a);
      }
      myfun([4, 5, 6]);

4、模板字符串

ES6 引入新的声明字符串的方式 『``』 '' ""

javascript 复制代码
  <script>
        //1. 声明
        // let str = `我是一个字符串哦!`;
        // console.log(str, typeof str);

        //2. 内容中可以直接出现换行符
        let str = `<ul>
                    <li>孙悟空</li>
                    <li>猪八戒</li>
                    <li>沙悟净</li>
                    <li>白骨精</li>
                    </ul>`;
        //3. 变量拼接 ${lovest}
        let lovest = '沈腾';
        let out = `${lovest}是我心目中最搞笑的演员!!`;
        console.log(out);
    </script>

5、字符串扩展

(1)、 includes函数

判断字符串中是否存在指定字符,返回布尔值, 语法:string.includes("xxx")

javascript 复制代码
<script>
      let myname = "hello";
      console.log(myname.includes("e")); //true
      console.log(myname.startsWith("o")); //false
      console.log(myname.endsWith("k")); //false
    </script>	

(2)、repeat函数

repeat()方法返回一个新字符串,表示将原字符串重复n次。str.repeat(数值)

javascript 复制代码
  <script>
      let res = "hello";
      console.log(res.repeat(1)); //hello
      console.log(res.repeat(0)); //""
      console.log(res.repeat(2.5)); //hellohello
      console.log(res.repeat("2"); //hellohello
    </script>

6、数值扩展

(1)、Number.EPSILON

JavaScript 表示的最小精度,一般用在浮点数运算上,

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16

javascript 复制代码
console.log(0.1 + 0.2 === 0.3);//false
  
      function equal(a, b) {
        if (Math.abs(a - b) < Number.EPSILON) {
          return true;
        } else {
          return false;
        }
      }
      console.log(equal(0.1 + 0.2, 0.3));//true

(2)二进制和八进制

javascript 复制代码
   let b = 0b1010;// 0b开头 二进制
      let o = 0o77;// 0o开头 八进制
      let d = 100; //十进制
      let x = 0xff;//0x开头 十六进制

(3)、 Number.isFinite

如果传递的值是有限数字,则返回true。 布尔值,字符串,对象,数组等所有其他内容均返回false:

javascript 复制代码
console.log(Number.isFinite(100));//true
console.log(Number.isFinite(100/0));//false
console.log(Number.isFinite(Infinity));//false
console.log(Number.isFinite(NaN));  //false

(4)、 Number.isNaN

检测一个数值是否为 NaN,只有对于NaN才返回true,非NaN一律返回false。

复制代码
console.log(Number.isNaN(123));//false

(5)、Number.parseInt Number.parseFloat

字符串转整数,必须以数字开头

javascript 复制代码
console.log(Number.parseInt('5211314love'));
 console.log(Number.parseFloat('3.1415926神奇'));

(6)、 Number.isInteger

判断一个数是否为整数

javascript 复制代码
 console.log(Number.isInteger(5));//true
 console.log(Number.isInteger(2.5));//false

(7)、Math.trunc

将数字的小数部分抹掉

javascript 复制代码
console.log(Math.trunc(3.5));//3

(8)、Math.sign

判断一个数到底为正数负数还是零,对于非数值,会先将其转换为数值。

javascript 复制代码
console.log(Math.sign(100));//1
console.log(Math.sign(0));//0
console.log(Math.sign(-20000));//-1	

7、数组扩展

(1)、Array.from()方法

将伪数组或可遍历对象转换为真正的数组。

javascript 复制代码
  <script>
      //   举例1:
      Array.from("12345"); // [1,2,3,4,5]
      //   举例2:
      let arr1 = {
        1: "a",
        2: "b",
        length: 3,
      };
      console.log(Array.from(arr1)); // [undefined, 'a', 'b']
      //举例3
      function test() {
        console.log(Array.from(arguments));// [1, 2, 3]
      }
      test(1, 2, 3);

       //举例4:选择器
      let divs = document.querySelectorAll("div");
      console.log(Array.from(divs));//[div, div, div]
    </script>

(2)、array.find() 方法

该方法主要应用于查找第一个符合条件的数组元素

它的参数是一个回调函数。

在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。

如果没有符合条件的元素,返回值为undefined

javascript 复制代码
<script>
      //   举例1:
      let arr1 = [1, 2, 3, 2];
      let res = arr1.find((item) => {
        //   console.log(item,'item');
        //return item>2
        return  item == 2
      });
      console.log(res); //2, 如果未找到,返回undefined

      //   举例2:
      let person = [
        { name: "张三", age: 16 },
        { name: "李四", age: 17 },
        { name: "王五", age: 18 },
      ];

      let target = person.find((item, index) => {
        return  item.name == "张三";
      });
      console.log(target.name);//张三
    </script>

(3)、array.findindex()方法

**定义:**用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1。

javascript 复制代码
  <script>
      let ary = [1,5, 10, 15];
      let index = ary.findIndex((item, index) => {
        return item > 9;
      });
      console.log(index); // 2   第一个比9大的数字在索引值为2的部位
    </script>

(4)、array.includes()方法

**定义:**判断某个数组是否包含给定的值,返回布尔值。

javascript 复制代码
<script>
      let ary = [1, 5, 10, 15];
      console.log(ary.includes(5)); //true
    </script>

(5)、Array.of()方法

将一组值转化为数组,即新建数组

javascript 复制代码
 <script>
      let arr1 = new Array(3);
      console.log(arr1); // [,,]
      let arr2 = Array.of(3);
      console.log(arr2); // [3]
    </script>

(6)、fill方法

使用自己想要的参数替换原数组内容,但是会改变原来的数组

可以传多个参数

1个参数:默认从数组第一位开始替换

2个参数:(替换的值,替换索引位置)

3个参数:(替换的值,替换索引开始位置,替换索引结束位置【不包括】)

javascript 复制代码
 <script>
      let arr1 = new Array(3).fill("hello");
      let arr2 = ["猪八戒", "孙悟空", "唐僧"].fill("kerwin", 1, 2);
      console.log(arr1); // ['hello', 'hello', 'hello']
      console.log(arr2); //  ['猪八戒', 'kerwin', '唐僧']
    </script>

(7)、最新数组方法

JavaScript中31个数组方法,包括es5,es6新增方法(关注收藏,持续更新)_js数组方法以及es6新增的数组方法有哪些-CSDN博客

(8)、spread 扩展运算符

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

javascript 复制代码
  <script>
        // 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
        //声明一个数组 ...
        const tfboys = ['易烊千玺','王源','王俊凯'];
        // => '易烊千玺','王源','王俊凯'


        // 声明一个函数
        function chunwan(){
            console.log(arguments);
        }


        chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
    </script>

扩展运算符的应用

javascript 复制代码
<body>
    <div></div>
    <div></div>
    <div></div>
    <script>
        //1. 数组的合并 
        const kuaizi = ['王太利','肖央'];
        const fenghuang = ['曾毅','玲花'];
        // 数组的合并 第一种方式
        // const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
        // 数组的合并 第二种方式
        const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
        console.log(zuixuanxiaopingguo);


        //2. 数组的克隆(深拷贝)
        const sanzhihua = ['E','G','M'];
        const sanyecao = [...sanzhihua];//  ['E','G','M']
        console.log(sanyecao);


        //3. 将伪数组转为真正的数组
        const divs = document.querySelectorAll('div');
        const divArr = [...divs];
        console.log(divArr);// arguments    
    </script>
</body>

8、对象拓展

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

(1)、简写对象

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

javascript 复制代码
 <script>
        //ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
        //这样的书写更加简洁
        let name = 'bdqn';
        let change = function(){
            console.log('我们可以改变你!!');
        }

       const school = {
        // name:name,//属性名和变量值一样,可以简写一个
        name,
        change, //外部定义的函数
        fun: function () {
          console.log("我是复杂写法");
        },
        improve() {
          //直接在对象里定义函数
          console.log("我是简写");
        },
      };

        console.log(school);
    </script>

注意:对象简写形式简化了代码,所以以后用简写就对了

(2)、 Object.is

比较两个值是否严格相等,与『===』行为基本一致 (+0 与 NaN)

javascript 复制代码
console.log(Object.is(120, 120));// === 
console.log(Object.is(NaN, NaN));// true
console.log(NaN === NaN);// false

(3) 、Object.assign

对象的合并,将原对象的所有可枚举属性,复制到目标对象,后面的对象会覆盖前面的对象一样的属性

Object.assign(target, object1,object2)的第一个参数是目标对象,后面可以跟一个或多个源对象作为参数。

target:参数合并后存放的对象

object1:参数1

object2:参数2

javascript 复制代码
const obj1 = {
        name: "tom",
        age: 18,
      };
      const obj2 = {
        name: "bob",
        age: 28,
        sex: "男",
      };
      console.log(Object.assign(obj1, obj2));
      //{name: 'bob', age: 28, sex: '男'}

(4) 、setPrototypeOf、 getPrototypeOf

可以直接设置对象的原型,不建议使用

setPrototypeOf( school, cities**)**

参数 1: 给谁设置原型对象 school

参数2:设置哪个原型对象 cities

javascript 复制代码
const school = {
        name: "bdqn",
      };
      const cities = {
        xiaoqu: ["北京", "上海", "深圳"],
      };
      // 设置原型
      Object.setPrototypeOf(school, cities);
      // 获取原型
      Object.getPrototypeOf(school);
      console.log(school);

9、函数扩展

1>、箭头函数

ES6 允许使用「箭头」(=>)定义函数。

箭头函数只能简写函数表达式,不能简写声明式函数

javascript 复制代码
 function fn() {} // 不能简写
 const fun = function () {}; // 可以简写
const obj = {
fn: function () {}, // 可以简写
};
(1)、 语法:() =>{}

():函数的形参

=>:必须的语法,指向代码块

{}:代码块

javascript 复制代码
   <script> 
       // ES6 允许使用「箭头」(=>)定义函数。
      //声明一个函数
      /* let fn = function(){
         } */
         
     /*  let fn = (a,b) => {
          return a + b;
      } */
      //调用函数
      // let result = fn(1, 2);
      // console.log(result);
       </script> 
(2)、箭头函数的特性

this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值,没有自己的this

不能作为构造实例化对象 会报错

不能使用 arguments 变量

箭头函数的简写

  1. 省略小括号, 当形参有且只有一个的时候

  2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的

执行结果

javascript 复制代码
 <script>    
      //箭头函数的特性
      //1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值,没有自己的this
      function getName() {
        console.log(this.name);
      }
      let getName2 = () => {
        console.log(this.name);
      };


      //设置 window 对象的 name 属性
      window.name = "北大青鸟";
      const school = {
        name: "bdqn",
      };


      //直接调用,this指向window
      // getName();
      // getName2();


      //call 方法调用
      // getName.call(school);  //指向school
      // getName2.call(school);  //指向window


      //2. 不能作为构造实例化对象  会报错
   /*    let Person = (name, age) => {
          this.name = name;
          this.age = age;
      }
      let me = new Person('xiao',30);
      console.log(me); */


      //3. 不能使用 arguments 变量
   /*    let fn = () => {
          console.log(arguments);
      }
      fn(1,2,3); */


      //4. 箭头函数的简写
      //1) 省略小括号, 当形参有且只有一个的时候
    /*   let add = n => {
          return n + n;
      }
      console.log(add(9)); */
      //2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
      // 而且语句的执行结果就是函数的返回值
     /*  let pow = (n) => n * n;
      console.log(pow(8)); */
    </script>

注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适

补充this指向问题汇总

1、作为普通函数被调用时--this指向全局对象window
javascript 复制代码
window.age = 18;
    function fn() {
        console.log(this.age);//18
    }
    fn()
2、对象方法里的this

当函数作为对象方法被调用时this指向该对象

javascript 复制代码
 var obj = {
        age: 18,
        fn: function () {
            console.log(this === obj);//true
            console.log(this.age);//18
        }

    }
    console.log(obj.fn());
3、构造函数里面的this

构造函数里的this指向 new创建的实例化对象(没有return的情况下)

如果构造函数内出现了return并且是一个object对象那么最终的运算结果返回这个对象

只要构造函数不返回数据或者返回基本数据类型 this仍然指向实例

javascript 复制代码
  function Fn() {
        this.age = 18;
        //此时a.age是return的结果20
        return {
          age: 20,
        };
      }
      let a = new Fn();
      console.log(a.age); //20
4、call&& apply&&bind

在function的原型上有三个方法 call apply bind,所有函数都是Function的实例,所以所有的函数都可以调用这三个方法,而这三个方法都是用来改变this指向的

**定义:**call(thisObj,Object) 调用一个对象的一个方法,以另一个对象替换当前对象。

**说明:**call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

javascript 复制代码
function fn(x, y) {
    console.log('加油');
    console.log(this);//this指向window
    console.log(x + y);
}
var o = {
    name: 'andy'
}
fn.call()//call 呼叫 可以调用函数
fn.call(o, 1, 2)//第一个值是this指向, 后边实参
fn.apply(o, [10, 20])//apply传递数组
fn.call(10, 20)//this-->new Numbe(10) x-->20 y-->undefined 
5、箭头函数中this

箭头函数里面没有自己的this 他只会从自己的作用域链上一层继承this

javascript 复制代码
 this.age = 20;
    var obj = {
        age: 18,
        fn: () => {
            console.log(this.age);//20
        }
    }
    obj.fn()

2> 参数默认值

(1)、 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)

javascript 复制代码
  function add(a, b, c = 10) {
        return a + b + c;
      }
      //let res1 = add(1, 2, 3);//6
      let res2 = add(1,1);//12
      cons
ole.log(res2);

(2)、 与解构赋值结合

javascript 复制代码
  function connect({ name, age, sex, price = "3000" }) {
        console.log(name);
        console.log(age);
        console.log(sex);
        console.log(price);
      }
      connect({
        name: "章三",
        age: 20,
        sex: "男",
        // price: 4000,
      });

(3)、这个默认值的方式箭头函数也可以使用

javascript 复制代码
const fn = (a = 10) => {
        console.log(a);
      };
      fn(); // 不传递参数的时候,函数内部的 a 就是 10
      fn(20); // 传递了参数 20 的时候,函数内部的 a 就是 20

注意: 箭头函数如果你需要使用默认值的话,那么一个参数的时候也需要写()

10、rest 参数

ES6 引入rest 参数,用于获取函数的实参,用来代替arguments

javascript 复制代码
   <script>
      // ES5 获取实参的方式
    /*   function date(){
          console.log(arguments);
      }
      date('大白','二黑','三孩'); */


      // rest 参数
     /*  function date(...args) {
        console.log(args); // filter some every map
      }
      date("大白", "二黑", "三孩"); */


      // rest 参数必须要放到参数最后
    /*   function fn(a,b,...args){
          console.log(a);
          console.log(b);
          console.log(args);
      }
      fn(1,2,3,4,5,6); */
    </script>

注意:rest 参数非常适合不定个数参数函数的场景

11、Symbol

(1)、Symbol 基本使用

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

undefined string symbol object null number boolean

Symbol 特点

  1. Symbol 的值是唯一的,用来解决命名冲突的问题

  2. Symbol 值不能与其他数据进行运算

  3. Symbol 定义的对象属性不能使用for...in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名

注: 遇到唯一性的场景时要想到Symbol

javascript 复制代码
script>
        //创建方式
        //创建Symbol方式1
        let s = Symbol();
        // console.log(s, typeof s);
        //创建方式2
      //  Symbol()函数可以接受一个字符串作为参数,
      //  表示对 Symbol 实例的描述。这主要是为了在控制台显示,比较容易区分。
      
        let s2 = Symbol('bdqn');//'bdqn'这个内容只是个标识
        let s3 = Symbol('bdqn');
        console.log('s2===s3',s2===s3);//false
        // 创建方式3  Symbol.for  
        // Symbol.for并不是每次都会创建一个新的symbol,它会先检索symbol表中是否有,没有再创建新的,有就返回上次存储的
        let s4 = Symbol.for('bdqn');
        let s5 = Symbol.for('bdqn');
        console.log('s4===s5',s4===s5);//true
        //注意事项
        //1:不能与其他数据进行运算
        //    let result = s + 100;
        //    let result = s > 100;
        //    let result = s + s;
    </script>

(2)、Symbol创建对象属性

可以给对象添加属性和方法

javascript 复制代码
<script>
      //向对象中添加方法 up down
      let game = {
        name: "俄罗斯方块",
        up: function () {},
        down: function () {},
      };

      //声明一个对象
      /* let methods = {
        up: Symbol(),
        down: Symbol(),
      };
      game[methods.up] = function () {
        console.log("我可以改变形状");
      };
      game[methods.down] = function () {
        console.log("我可以快速下降!!");
      };
      console.log(game); */

        let youxi = {
            name:"狼人杀",
            [Symbol('say')]: function(){
                console.log("我可以发言")
            },
            [Symbol('zibao')]: function(){
                console.log('我可以自爆');
            }
        }
      console.log(youxi);
    </script>

(3)、Symbol的内置对象

除了定义自己使用的Symbol 值以外,ES6 还提供了11 个内置的Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。

|---------------------------|----------------------------------------------------------------------------------|
| Symbol.hasInstance | 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法 |
| Symbol.isConcatSpreadable | 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。 |
| Symbol.species | 创建衍生对象时,会使用该属性 |
| Symbol.match | 当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。 |
| Symbol.replace | 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。 |
| Symbol.search | 当该对象被str.search(myObject)方法调用时,会返回该方法的返回值。 |
| Symbol.split | 当该对象被str.split(myObject)方法调用时,会返回该方法的返回值。 |
| Symbol.iterator | 对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器 |
| Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
| Symbol.toStringTag | 在该对象上面调用toString方法时,返回该方法的返回值 |
| Symbol.unscopables | 该对象指定了使用with关键字时,哪些属性会被with环境排除。 |

12、迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator 接口,就可以完成遍历操作。(Iterator 接口就是对象里面的一个属性)

Iterator 接口就是对象的一个属性

Iterator 的作用有三个:

一是为各种数据结构,提供一个统一的、简便的访问接口;

二是使得数据结构的成员能够按某种次序排列;

三是 ES6 创造了一种新的遍历命令for...of 循环,Iterator 接口主要供for...of循环

  1. ES6 创造了一种新的遍历命令for...of 循环,Iterator 接口主要供for...of 消费

  2. 原生具备iterator 接口的数据(可用for of 遍历)

a) Array

b) Arguments

c) Set

d) Map

e) String

f) TypedArray

g) NodeList

  1. 工作原理(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

(5) 每调用next 方法返回一个包含value 和done 属性的对象

done:是否循环完毕

**注:**迭代器就是按照一定的顺序对元素进行遍历的过程

javascript 复制代码
   <script>
      //声明一个数组
      const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];


      //使用 for...of 遍历数组   
      for (let v of xiyou) {
        console.log(v);
      }


      let iterator = xiyou[Symbol.iterator]();
      console.log(iterator);
      
      //调用对象的next方法
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());
    </script>

13、生成器

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

(1)、生成器基本语法

通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号(*)可以紧挨着function关键字,也可以在中间添加一个空格

javascript 复制代码
<script>
      //生成器其实就是一个特殊的函数
      //异步编程  纯回调函数  node fs  ajax mongodb

      //yield 函数代码的分隔符,分割代码
      function* cook() {
        let i = 1;
        console.log(`我被执行了${i}次`);
        yield "盛米";
        i++;
        console.log(`我被执行了${i}次`);
        yield "淘米";
        i++;
        console.log(`我被执行了${i}次`);
        yield "煮米";
        i++;
        console.log(`我被执行了${i}次`);
      }

      let iterator = cook(); //返回一个迭代器对象,里面有个next()方法
      //函数不会一下子执行完毕,会以yield为分割线,调一次next,执行一次
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());

      //遍历
      // for(let v of cook()){
      //     console.log(v);
      // }
    </script>

代码说明:

  1. cook()前的星号 * 表明它是一个生成器

  2. 生成器函数返回的结果是迭代器对象,调用迭代器对象的next 方法可以得到yield 语句后的值

  3. yield 相当于函数的暂停标记,每当执行完一条yield语句后函数就会自动停止执行,也可以认为是函数的分隔符,每调用一次next方法,执行一段代码

  4. next 方法可以传递实参,作为yield 语句的返回值

5)yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误

(2)、生成器函数参数

**概念:**next('BBB')传入的参数作为上一个next方法的返回值。

javascript 复制代码
  <script>
      function * gen(arg) {
        console.log(arg);//AAA
        let one = yield "aaa";
        console.log(one);//BBB
        let two = yield "bbb";
        console.log(two);//CCC
        let three = yield "ccc";
        console.log(three);//DDD
      }

      //执行获取迭代器对象
      let iterator = gen("AAA ");
      console.log(iterator.next()); //{value: 'aaa', done: false}
      //next方法可以传入的实参,作为yield语句整体返回的结果
      console.log(iterator.next("BBB"));
      console.log(iterator.next("CCC"));
      console.log(iterator.next("DDD"));
    </script>
(3)、生成器函数实例

(3)、生成器函数实例

javascript 复制代码
 <script>
      // 异步编程   文件操作 网络操作(ajax, request) 数据库操作
      // 需求:1s 后控制台输出 111  2s后输出 222  3s后输出 333
      // 回调地狱(一层套一层,不停回调)
      /* setTimeout(() => {
            console.log(111);
            setTimeout(() => {
                console.log(222);
                setTimeout(() => {
                    console.log(333);
                }, 3000);
            }, 2000);
        }, 1000); */

      // 生成器函数解决回调地域
      //生成3个异步函数
      function one() {
        setTimeout(() => {
          console.log(111);
          iterator.next(); //函数one执行完毕后,调用next(),执行下一个异步函数
        }, 1000);
      }

      function two() {
        setTimeout(() => {
          console.log(222);
          iterator.next(); //函数two执行完毕后,调用next(),执行下一个异步函数
        }, 2000);
      }

      function three() {
        setTimeout(() => {
          console.log(333);
          iterator.next(); //函数three执行完毕后,调用next(),执行下一个异步函数
        }, 3000);
      }
      //用生成器函数将三个异步函数放在yield语句中
      function* gen() {
        yield one();
        yield two();
        yield three();
      }

      //调用生成器函数
      let iterator = gen();
      iterator.next(); //调用一次next执行一个yield语句,这个只会执行one()回调
    </script>

14、Promise

(0)、回调地狱

回调地狱:就是回调函数嵌套过多导致的

当一个回调函数嵌套一个回调函数的时候

就会出现一个嵌套结构

当嵌套的多了就会出现回调地狱的情况

比如我们发送三个 ajax 请求

第一个正常发送

第二个请求需要第一个请求的结果中的某一个值作为参数

第三个请求需要第二个请求的结果中的某一个值作为参数

javascript 复制代码
 <script>
      function fn() {
        setTimeout(function () {
          console.log("111");
          setTimeout(function () {
            console.log("222");
            setTimeout(function () {
              console.log("333");
            }, 1000);
          }, 2000);
        }, 3000);
      }
      fn();
    </script>

(1)、什么是promise

Promise是ES6异步编程的一种解决方案(目前最先进的解决方案是async和await的搭配(ES8),但是它们是基于promise的)

从语法上讲,Promise是一个对象或者说是构造函数,用来封装异步操作并可以获取其成功或失败的结果。

(2)、Promise对象的状态:

a **、**对象的状态不受外界影响。

Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

pending: 等待中,或者进行中,表示还没有得到结果

resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行

rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行

b **、**Promise对象三种状态不受外界影响,三种的状态的变化途径只有两种。

从"未完成"到"成功"

从"未完成"到"失败"

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是"承诺",一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。

c、Promise 的最终结果只有两种。

异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。

异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。

(3)、Promise语法格式

javascript 复制代码
//写法一
new Promise(function (resolve, reject) {
  // resolve 表示成功的回调
  // reject 表示失败的回调
}).then(function (res) {
  // 成功的函数
}).catch(function (err) {
  // 失败的函数
})
//写法二
new Promise(function (resolve, reject) {
  // resolve 表示成功的回调
  // reject 表示失败的回调
}).then(function (res) {
  // 成功的函数
},function(res){
    // 失败的函数
})

出现了new关键字,就明白了Promise对象其实就是一个构造函数,是用来生成Promise实例的。能看出来构造函数接收了一个函数作为参数,该函数就是Promise构造函数的回调函数,该函数中有两个参数resolve和reject,这两个参数也分别是两个函数!

简单的去理解的话

resolve函数的目的是将Promise对象状态变成成功状态,在异步操作成功时调用,将异步操作的结果,作为参数传递出去。

reject函数的目的是将Promise对象的状态变成失败状态,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

注意:then方法可以接受两个函数 ,第一个函数为 promise状态为成功的回调函数 ,第二个函数为 promise状态为失败的回调函数 可以不写,一般用catch方法捕获promise状态为失败的异常信息)

(4)、代码示例

javascript 复制代码
  const promise = new Promise((resolve,reject)=>{
            //异步代码
            setTimeout(()=>{
                // resolve(['111','222','333'])
                reject('error')
            },2000)
        })
        //写法一
        promise.then((res)=>{
            //兑现承诺,这个函数被执行
            console.log('success',res);
        }).catch((err)=>{
            //拒绝承诺,这个函数就会被执行
            console.log('fail',err);
        })
        //写法二
        promise.then(
          function (value) {
            console.log(value);
          },
          function (reason) {
            console.error(reason);
          }
        );

(5)、Promise封装Ajax

javascript 复制代码
<script>
      // 接口地址: https://api.apiopen.top/getJoke
      const p = new Promise((resolve, reject) => {
        //1. 创建对象
        const xhr = new XMLHttpRequest();

        //2. 初始化
        xhr.open("GET", "https://api.apiopen.top/getJoke");

        //3. 发送
        xhr.send();

        //4. 绑定事件, 处理响应结果
        xhr.onreadystatechange = function () {
          //判断
          if (xhr.readyState === 4) {
            //判断响应状态码 200-299
            if (xhr.status >= 200 && xhr.status < 300) {
              //表示成功
              resolve(xhr.response);
            } else {
              //如果失败
              reject(xhr.status);
            }
          }
        };
      });

      //指定回调
      p.then(
        function (value) {
          console.log(value);
        },
        function (reason) {
          console.error(reason);
        }
      );
    </script>

(6)、promise的对象方法

p1,p2,p3为promise的实例对象

Promise.then() 方法

then方法的返回结果是 Promise 对象, 返回对象状态由回调函数的执行结果决定,结果有以下:

a. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值

b. 是 promise 对象,内部返回的状态,就是它的状态

c. 抛出错误 返回失败的promise状态

链式调用 可以改变回调地狱的情况

javascript 复制代码
 <script>
      //创建 promise 对象
      const p = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("用户数据");
          // reject('出错啦');
        }, 1000);
      });
      const result = p.then(
        (value) => {
          console.log(value);
          //1. 非 promise 类型的属性
          // return 'iloveyou';
          //2. 是 promise 对象
          // return new Promise((resolve, reject)=>{
          //     // resolve('ok');
          //     reject('error');
          // });
          //3. 抛出错误
          // throw new Error('出错啦!');
          throw "出错啦!";
        },
        (reason) => {
          console.warn(reason);
        }
      );

      //链式调用
    p.then(value=>{}).then(value=>{}); 
    </script>

Promise.catch()

一般用catch方法捕获promise状态为失败的异常信息

javascript 复制代码
 <script>
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                //设置 p 对象的状态为失败, 并设置失败的值
                reject("出错啦!");
            }, 1000)
        });
        // p.then(function(value){}, function(reason){
        //     console.error(reason);
        // });
        
        p.catch(function(reason){
            console.warn(reason);
        });
    </script>

Promise.all()

并发处理多个异步任务,所有任务都执行完成才能得到结果

javascript 复制代码
Promise.all( [p1,p2,p3] ) .then ( (result) => {consoleog (result)
})

Promise.race()

只返回异步任务数组中第一个执行完的结果,其他任务仍在执行,不过结果会被抛弃

应用场景:

几个接口返回一样的数据,哪个快用哪个

javascript 复制代码
Promise.race ( [p1,p2] ).then ( (result)=>{
console. log (result)
})

15、set

(1)、set基本知识

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

实例的属性和方法

size:返回Set实例的成员总数。

Set.prototype.add(value):添加某个value。

Set.prototype.delete(value):删除某个value,返回一个布尔值,表示删除是否成功。

Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。

Set.prototype.clear():清除所有成员,没有返回值。

javascript 复制代码
 <script>
        //声明一个 set
        let s = new Set();
        let s2 = new Set(['张三','李四','王五','赵六']);
        
        //元素个数
        // console.log(s2.size);
        //添加新的元素
        // s2.add('jack');
        //删除元素
        // s2.delete('李四');
        //检测
        // console.log(s2.has('王五'));
        //清空
        // s2.clear();
        // console.log(s2);
        //遍历元素
        for(let v of s2){
            console.log(v);
        }
        
    </script>

set遍历

Set.prototype.keys():返回键名的遍历器

Set.prototype.values():返回键值的遍历器

Set.prototype.entries():返回键值对的遍历器

Set.prototype.forEach():遍历每个成员

javascript 复制代码
let arr = new Set(["red", "green", "blue"]);
      // 返回键名
      for (let item of arr.keys()) {
        // console.log(item);//red green blue
      }

      // 返回键值
      for (let item of arr.values()) {
        // console.log(item);//red green blue
      }
      // set 键名=键值
      // 返回键值对
      for (let item of arr.entries()) {
        // console.log(item);// ['red', 'red']   ['green', 'green'] ['blue', 'blue']
      }
      // set也有forEach()方法
      arr.forEach((value, key) => console.log(key + " : " + value));

(2)、set实践

javascript 复制代码
  <script>
      let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
      //1. 数组去重
      //   let result = new Set(arr);
      //   result = [...result];
      //   console.log(result);
      //2. 交集
      let arr2 = [4, 5, 6, 5, 6];
      /* 可以先去重,避免做无用对比 */
      //   let result = [...new Set(arr)].filter(item => {
      //       let s2 = new Set(arr2);//数组2去重后的结果  4 5 6
      //       if(s2.has(item)){
      //           return true;
      //       }else{
      //           return false;
      //       }
      //   });
      //简化版本
      // let result = [...new Set(arr)].filter((item) => new Set(arr2).has(item));
      //console.log(result);


      //3. 并集
      // let union = [...new Set([...arr, ...arr2])];
      // console.log(union);


      //4. 差集
      // let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
      // console.log(diff);
    </script>

16、Map

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

Map 的属性和方法:

  1. size 返回Map 的元素个数

  2. set 增加一个新元素,返回当前Map

  3. get 返回键名对象的键值

  4. has 检测Map 中是否包含某个元素,返回boolean 值

  5. clear 清空集合,返回undefined

javascript 复制代码
<script>
        /* map升级后的对象,键名可以是对象 */
        //声明 Map
        let m = new Map();


        //添加元素 set()
        m.set('name','bdqn');//键名:字符串
        m.set('change', function(){//键名:字符串
            console.log("我们可以改变你!!");
        });
        let key = {
            school : '北京大学'
        };


          m.set(key, ['北京','上海','深圳']);//键名:对象


        //size
        // console.log(m.size);


        //删除
        // m.delete('name');


        //获取  get()
        // console.log(m.get('change'));
        // console.log(m.get(key));


        //清空  clear()
        // m.clear();


        //遍历
        // for(let v of m){
        //     console.log(v);
        // }


        console.log(m);


    </script>

17、class类

JavaScript 语言中,生成实例对象的传统方法是通过构造函数,ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

1> class初体验

javascript 复制代码
 <script>
      // //es5通过构造函数实现
      // function PersonO(username, password) {
      //   this.username = username;
      //   this.password = password;
      // }
      // // 添加方法
      // PersonO.prototype.getstr = function () {
      //   console.log("用户名:" + this.username + ",密码:" + this.password);
      // };
      // // 实例化对象
      // const po1 = new PersonO("章三", "abc123");
      // console.log(po1);
      // po1.getstr();

      // es6实现  class方法实现
      class PersonN {
        //构造方法  constructor名字不能修改
        // 当我们new实例对象的时候,这个方法自动执行
        constructor(username, password) {
          this.username = username;
          this.password = password;
        }
        //方法必须使用该语法, 不能使用 ES5 的对象完整形式
        getstr() {
          console.log("用户名:" + this.username + ",密码:" + this.password);
        }
        //ES5 的对象完整形式  报错
        // getstr:function () {}
      }
      const pn1 = new PersonN("123456", "789012");
      pn1.getstr();
    </script>

说明:使用class关键词 声明类,constructor为构造方法,一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加,

this关键字则代表实例对象,

getstr()为普通方法,不要用es5完整写法,getstr()存在 prototype上。

pn1.constructor === pn1.prototype.constructor // true

2> 类的静态成员

es5可以直接给构造函数添加属性,方法,这些属性方法不在这个构造函数实例的对象身上

对应的es6中,类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为"静态方法"。

javascript 复制代码
 <script>
      // es5
      function Phone() {}
      // 给Phone添加静态属性
      Phone.name = "手机";
      Phone.call = function () {
        console.log("我可以打电话");
      };

      //实例化对象
      let apple = new Phone();
      // console.log(apple.name); //undefined
      //apple.change(); //报错  实例身上是没有构造函数身上的属性和方法

      // Phone.call(); //我可以打电话

    class PhoneN{
        static  name='手机'
        static  game(){
          console.log('我可以打游戏');
        }
      }
      let  p1=new PhoneN()
      console.log(p1.name);//undefined
      console.log(PhoneN.name);//手机
    </script>

3> 类的继承

(1)、es5的继承
javascript 复制代码
<script>
      //手机   父级构造函数
      function Phone(brand, price) {
        this.brand = brand;
        this.price = price;
      }
      Phone.prototype.call = function () {
        console.log("我可以打电话");
      };
      //智能手机   子级构造函数
      function SmartPhone(brand, price, color, size) {
        //通过call方法改变this指向,指向SmartPhone的实例对象
        Phone.call(this, brand, price);
        //子类独有的属性
        this.color = color;
        this.size = size;
      }
      //设置子级构造函数的原型   让SmartPhone的实例对象有父类的属性方法
      SmartPhone.prototype = new Phone();
      SmartPhone.prototype.constructor = SmartPhone;
      //声明子类的方法
      SmartPhone.prototype.photo = function () {
        console.log("我可以拍照");
      };
      SmartPhone.prototype.playGame = function () {
        console.log("我可以玩游戏");
      };
      //实例化对象
      const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
      console.log(chuizi);
    </script>
(2)、es6的继承
javascript 复制代码
 <script>
 // 定义父类
      class Student {
        //构造方法
        constructor(realname, age) {
          this.realname = realname;
          this.age = age;
        }
        //父类的成员属性
        play(str) {
          console.log("我会玩" + str);
        }
      }
      //定义子类
      class ItStudent extends Student {
        //构造方法
        constructor(realname, age, major) {
          //调用父类的方法,相当于Student.call(this,realname, age)
          super(realname, age);
          this.major = major;
        }
        //子类的成员属性
        program(type) {
          console.log("我会编程的语言是:" + type);
        }
        // 子类对父类方法的重写
        play(str) {
          console.log("我只学习,不玩" + str);
        }
      }
      //实例化对象
      const It1 = new ItStudent("张三", 20, "大数据");
      console.log(It1.realname);
      It1.play("游戏"); //我只学习,不玩游戏
    </script>

说明:Class 可以通过extends关键字实现继承,让子类继承父类的属性和方法。ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。

4> getter和setter设置

javascript 复制代码
<script>
      // get 和 set
      class Phone {
        // get 监测动态属性的变化
        get price() {
          console.log("价格属性被读取了");
          return "iloveyou";
        }
        // set 对更改设置的值做判断,合法怎么办,不合法怎么办
        set price(newVal) {
          console.log("价格属性被修改了");
        }
      }
      //实例化对象
      let s = new Phone();
      console.log(s.price);//输出price属性,只要读取,就会执行get后面对应的函数代码,函数的返回值就是属性的返回值
      s.price = "9.9";//更改price属性,只要更改,就会执行set后面对应的函数代码
    </script>

18、模块化(module)

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

1、模块化的优势
  1. 防止命名冲突

  2. 代码复用

  3. 高维护性,可以对某些模块化升级

2、ES6 模块化语法

模块功能主要由两个命令构成:export 和import。

export 命令用于规定模块的对外接口,对外暴露

import 命令用于输入其他模块提供的功能 ,引入暴露的文件

1> 暴露语法汇总

(1)、 分别暴露

javascript 复制代码
//m1.js  分别暴露
export let school = 'bdqn';
export function teach() {
    console.log("我们可以教给你开发技能");
}
(2)、统一暴露
javascript 复制代码
// m2.js  统一暴露
let school = 'bdqn';
function findJob(){
    console.log("我们可以帮助你找工作!!");
}
export {school, findJob};
(3)、默认暴露
javascript 复制代码
//m3.js 默认暴露
export default {
    school: 'bdqn',
    change: function(){
        console.log("我们可以改变你!!");
    }
}

export export default 的区别 ( 面试题 )

1、两者均可用于导出常量、函数、文件、模块;

2、在一个文件中可以多次使用export,但是export default只能用一次;

3、通过export输出的,在import导入时需要使用{},export default不需要;

4、export与export default不可同时使用;

2> 引入暴露文件语法
(1)、通用方式
javascript 复制代码
 //1. 通用的导入方式
      //引入 m1.js 模块内容
      import * as m1 from './js/m1.js'
      //引入 m2.js 模块内容
      import * as m2 from "./js/m2.js";
      //引入 m3.js
      import * as m3 from "./js/m3.js";
      console.log(m1);
(2)、解构附值
javascript 复制代码
//2. 解构赋值形式的导入方式
      import { school, teach } from "./js/m1.js";
      //用别名
      import {school as yyzx, findJob} from "./js/m2.js";
     
      import {default as m3} from "./js/m3.js";
(3)、简易形式
javascript 复制代码
    //3. 简便形式的导入方式   针对默认暴露
      import m3 from "./js/m3.js";
3> 建立入口文件形式
javascript 复制代码
// app.js  入口文件
//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";


console.log(m1);
console.log(m2);
console.log(m3);
<!--index.html  引入 入口文件 -->
    <script src="./js/app.js" type="module"></script>
相关推荐
朴拙数科19 小时前
技术长期主义:用本分思维重构JavaScript逆向知识体系(一)Babel、AST、ES6+、ES5、浏览器环境、Node.js环境的关系和处理流程
javascript·重构·es6
天下代码客1 天前
【八股】介绍Promise(ES6引入)
前端·ecmascript·es6
盛夏绽放2 天前
ES6 新特性全面总结
前端·ecmascript·es6
东东__net4 天前
19_20 js es6
前端·javascript·es6
henujolly4 天前
es6的100个问题
前端·ecmascript·es6
程序员林北北6 天前
深入解析 Vue3 响应式系统:原理、性能优化与应用场景
前端·javascript·vue.js·typescript·前端框架·html·es6
2401_878454536 天前
Es6进阶
前端·javascript·es6
羽沢317 天前
ES6-Symbol
linux·服务器·es6
海晨忆8 天前
JS—ES5与ES6:2分钟掌握ES5与ES6的区别
开发语言·javascript·es6·es5与es6的区别
HappyAcmen8 天前
关于ES6/7的前端面试题及其解析
前端·ecmascript·es6