es6总结

1.三种声明变量的区别 var let const

       es5:   var
            1、 var变量提升机制
            2、 var 声明的变量是全局作用域 或 局部作用域
            3、 var 可以重复声明同名变量  
            4、 var 可以先声明  后赋值
            5、 var 声明的变量可以改变变量的值
    6、 var在if语句和for循环,使用var声明的变量是全局的

        es6:   let   const
            1、let  const 声明变量时不存在 变量提升
            2、let  const 声明的都是块级作用域 (可以声明全局 或者 局部)
            3、let const 不允许重复声明同名的变量
            4、let 可以先声明  后赋值, 但是 const 必须声明的同时并赋值
            5、let 声明的变量可以改变变量的值, 但是 const 声明的变量, 如果是基本数据类型, 则不允许更改变量的值, 如果是引用数据类型,可以修改数据的具体的值,但是不能直接修改地址
            6、let 声明的变量存在暂时性死区
    7、let声明的变量不会暴露给window
const  不允许改变变量的值本质:
   const实际上可以修改堆内存的地址,修改不了堆内存的地址(相当于对下面的内容进行总结)
            const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了
解构:
       1、扩展运算符都是进行的浅拷贝
     2、如果扩展运算符在最后一个前提没有声明例如 var str='hel' let [a,b,c,..d] = str 对应的str不会为underfind 会是[]
     3、指定默认值的前提条件下是没有对应的值存在的情况下 eg: let arr = [10,20,30] let [a = 100,b,c, d=20]=arr  => 100 20 430 20
     4、解构访问对象不存在的值 结果为undefined
     5、合并对象 键名相同覆盖(后者覆盖前者)
        6、对象键名重新赋值的情况下不能带引号
指数运算符:2**3 等于2×2×2; 2**3**2 计算方法是先算3的平方然后再算2的平方 计算规律是从右向左算
链判断运算符:?.查找对象深层的属性或方法时 会存在短路情况
 1     let person = {
 2             message:{
 3                 body:{
 4                    title:'宁子'
 5                     //  info 
 6                 }
 7             }
 8         }
 9        let info = person.message.body.info  || '默认值'  // 不存在info这个属性会输出默认值这三个字
10          let info = person.message.body.info ? person.message.body.info : '默认值'

null判断运算符:?? 只有左侧属性为null或nudefined时,才能生效

1  let child = {
2             name:"张三",
3             age:0
4         }
5 
6         // let age = child.age || 100;
7         //  ?? 类似于  || 运算符
8         let age = child.age ?? 100;
9         console.log(age);  =>0

 

 
 
    
2. 数组的遍历 //  for循环  for-in循环   forEach()
      es5   map()  filter()  some()   every()  reduce()  findeIndex() ...
        //  map() =============  遍历数组, 返回的是一个新数组 (通过指定的规则 把原数组中的值映射到新数组对应的值)  参数 是函数, 函数指定映射规则
 1         // =============== es5   map()  filter()  some()   every()  reduce()  findeIndex() ... 
 2         //  map() =============  遍历数组, 返回的是一个新数组 (通过指定的规则 把原数组中的值映射到新数组对应的值)  参数 是函数, 函数指定映射规则
 3         // let newArr = [1, 2, 3, 4].map(function(item, index){
 4         //     console.log(item, index);
 5         //     //  必须通过 return 语句 指定映射规则 ; 通过return 返回新数组的元素
 6         //     // return item * 10;
 7         //     // return 'helllo';
 8         // })
 9         // console.log(newArr);
10 
11         // =============== 经典面试题
12         // let res = [1, 2, 3].map(parseInt);  // map 方法中的第一个参数是 数组中的元素 ,第二个参数是数组的索引值   
13         // let res = ['1', '2', '3'].map(parseInt); 
14         // console.log(res);  // [1, NaN, NaN] 
15 
16         // [1, 2, 3].map(function())
17 
18 
19         // ==================== some() 遍历数组 返回值是布尔类型  false  true 
20         // 检索数组中是否有符合要求的元素, 只要有一个符合要求,则结果是true    全部不符合则为 false
21         // let res =  [12, 23, 33, 44].some(function(item, index, arr){
22         //     // console.log(item, index, arr);
23         //     return item > 50
24         // })
25         //  every()  和 some() 相对应 ,   every()要求的是全部满足要求 为 true   否则false 
26         // let res = [12, 23, 33, 44].every(function (item, index, arr) {
27         //     // console.log(item, index, arr);
28         //     return item > 3
29         // })
30         // console.log(res);
31 
32 
33         //  =================== filter() 过滤数组   返回值是一个新数组, 结果是符合要求的数组中的元素
34         // let res = [12, 34, 45, 56].filter(function(item, index){
35         //     console.log(item, index);
36         //     return item > 40
37         // })
38         // console.log(res);
39 
40 
41         // ======================= reduce()  累加器
42         //  
43         // let res = [10, 20, 30, 40].reduce(function(item, index){
44         //     console.log(item, index);
45         //     return item + index;
46         // })
47 
48         //  没有指定初始值 initValue 的时候,priviousValue  代表数组中的第一个元素 , currentValue 当前正在遍历的元素(从第二个开始依次代表数组中的每个元素)  currentIndex  当前遍历元素的索引值
49         // let res = [10, 20, 30, 40].reduce(function(priviousValue,currentValue, currentIndex){
50         //     console.log(priviousValue, currentValue, currentIndex);
51         //     return priviousValue + currentValue;
52         // })
53 
54         //  提供了初始值  100 , priviousValue 就是初始值,  currentValue 依次代表数组中的元素 
55         let res = [10, 20, 30, 40].reduce(function(priviousValue, currentValue, currentIndex){
56             console.log(priviousValue, currentValue, currentIndex);
57             return priviousValue + currentValue;
58         }, 100)
59 
60         // console.log(res);
3.  解构赋值   字符串  对象   数组   
  字符串和数组是通过索引值来解构的 数组是通过key解构的
  扩展运算符只适合一维数组,二维的无效 结果只有两种 数组或者是对象   扩展运算符 只能放到最后边
4.箭头函数
1  //  如果函数体只有一条语句是返回值, 则可以省略return 语句 ;直接写 
2         // let sum = (a, b) => a + b;
1 / 如果参数只有一个,则可以省略 ()  
2         // let sqrt = x => x * x;

注意:箭头函数中的this继承父级的this

rest 参数形式为(“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
箭头函数体内没有自己的this对象,所以在使用的时候,其内部的this就是定义时所在环境的对象,而不是使用时所在环境的对象。
不能给箭头函数使用 call apply bind 去改变其内部的this指向
箭头函数体内没有arguments对象,如果要用,可以用Rest参数代替。
不可以当作构造函数,不可以使用new命令,否则会抛出一个错误。

5.新增的symbol

  Symbol 新增的基本数据类型  独一无二的值
  Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
   Symbol 作为键名  不能使用 . 运算符
        ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
        应用场景: 对 对象进行扩展

        Set : 不允许存在重复的值 应用场景 数组去重

        Map : 存储数据的键 可以是任意类型

          对象  键 只能是 字符串类型, 它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的                    对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。。
6.  for-of 循环    只能遍历具有  Iterator 接口的数据 
 普通的对象不能通过for-of遍历 要想遍历就要在对象里面创建接口
 键: [Symbol.iterator]:function(){}
7.promise() : 解决回调地狱的问题  , 但是也会造成 then 的过度使用 简单来说是一个容器 是异步编程的一种解决方案
   Promise.all() :
        Promise.race():
        相同点:
        Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理。

        不同点:
            all() 如果是成功, 则 等到所有的promise 实例返回结果, 如果存在一个失败。则返回失败的结果

            race() 不管是成功还是失败, 哪个promise 实例对象的状态率先改变则返回谁的状态
8.21-async和await  
  asyns函数使得异步操作变得更加方便 返回的是一个promise对象可以通过then ()链式调用本质就是Generator函数的语法糖
   async  await 把异步操作以同步的形式进行显示 (本质还是异步操作)
  正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值
        await 用于async 函数内部   await 后边是一个Promise对象 也可以是原始类型的值(数值,布尔值)
         async  await  通过 try - catch 进行异常捕获
 1    function ajax(url) {
 2             return new Promise((resolve, reject) => {
 3                 let xhr = new XMLHttpRequest();
 4                 xhr.open('get', url);
 5                 xhr.send();
 6                 xhr.onreadystatechange = function () {
 7                     if (xhr.status == 200 && xhr.readyState == 4) {
 8                         // console.log(2222, JSON.parse(xhr.responseText));
 9                         // resolve(JSON.parse(xhr.responseText))
10                         reject(xhr.statusText)
11                     }                
12                 }
13             })
14         }
15 
16         // ajax(url).then(res => res)
17 
18         
19         //  async 函数
20         async function fun(){
21             //  await 等待的意思 ;   await 执行之后得到的结果是 异步操作请求回来的数据
22             //  await 简化了then(res => res)
23           let res =  await ajax('https://cnodejs.org/api/v1/topics');
24             console.log(res);
25         }
26 
27         fun()

9. class类 相当于构造函数的升级迭代 只不过是换了一种方式

无论是构造函数还是class this都指向实例化对象

 es6定义类的时候函数不带()里面的构造器带括号
只要执行了new class里面的构造器就会自动调用执行
静态方法相当于在构造器前面加上 static 就行了  静态方法不会被继承
 es5 的构造函数  (es5 类)  es6 class (类)
class有私有的属性和方法 写在constructor构造器里面 只属于class本身不能被继承
创建类的时候 类本身就是一个对象
私有的方法和属性可以被继承 不能被外部访问
静态方法和静态属性可以被子类继承 但是子类的实例化对象不能继承
类的私有属性只能在class里面引用 在外部调用的话会报错
继承是通过extends关键词:
 1 //  定义父类
 2         class School{
 3             constructor(name, address){
 4                 console.log('子类的super方法');
 5                 this.name = name;
 6                 this.address = address;
 7             }
 8             teaching(){
 9                 console.log('学校都是教书育人, 象牙塔');
10             }
11         }
12         //  继承 extends 关键
13         class Yunhe extends School{
14             constructor(teacher, name, address){
15                 //  ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。
16                 super(name, address);
17                 //  ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。这就是为什么 ES6 的继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,没有这一步就无法继承父类。
18                 //  给子类添加属性 必须在 super() 方法之后
19                 this.teacher = teacher;
20             }
21         }
22         // 另一个需要注意的地方是,在子类的构造函数中,只有调用super()之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,必须先完成父类的继承,只有super()方法才能让子类实例继承父类。
23         let wxs = new Yunhe('教师', '云和数据', '高新区')
24         console.log(wxs);

 

共有的属性和方法默认添加到了原型对象上
 1  class Person{
 2             constructor(name, age){
 3                 this.name = name;
 4                 this.age = age;
 5             }
 6         }
 7         //  继承 extends   
 8         //  子类必须在constructor()方法中调用super(),否则就会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。
 9         class Child extends Person{
10             constructor(name, age, hari){
11                 //  添加子类自己的实例属性和方法。 必须先调用 super() 方法
12                 super(name, age)
13                 this.hari = hari;
14             }
15             say(){
16                 console.log('嫦娥');
17             }
18         }
19 
20         // let c1 = new Child('红的头发')
21         let c1 = new Child('小明', 18, '黄色头发')
22         console.log(c1);

class类的get和set  

get和set属于数据拦截

   get 后边的就是拦截的属性名
 set 后边的就是拦截之后设置的
     类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
     
  静态的方法  不会被子类 继承的 ; 通过类本身进行调用
   如果静态方法包含this关键字,这个this指的是类,而不是实例。
10.模块化开发
  es6 提供两个命令  export   import :
        模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
   export 模块的导出
        import 模块的导入
       
        script 标签 type 属性 可以定义模块  
         <script type="module" src='url'></script>

        在服务器环境下测试
导入文件:
1    //  import 导入模块
2         //  导入模块时 需要使用解构形式 
3         import {num, count} from './module/first.js'
4         //  引入默认模块  a 就是给默认模块起的名字(默认模块的名字是自定义的)
5         import a from './module/first.js'
6         console.log(num);
7         count()
8         a(10)

导出文件:

 1 //  模块系统  
 2 //  一个文件可以导出多个接口
 3 //  export 导出模块
 4 export const num = 100;
 5 
 6 export function count(){
 7     console.log('count++');
 8 }
 9 
10 export const person = {
11     name:'张三',
12     age:19
13 }
14 
15 //  导出默认的模块    一个文件系统只能有唯一一个默认的导出模块
16 //  导出默认模块 
17 export default function score(num){
18     console.log(++num);
19 }

 

posted @ 2022-06-08 13:58  请善待容嬷嬷  阅读(29)  评论(0编辑  收藏  举报