zoukankan      html  css  js  c++  java
  • ECMASctipt6总结

    1.let 变量声明以及特性

      声明变量

           let a;
        let b, c, d;
        let e = 1;
        let f = 2, g = 3;    

      特性

        1.不能重复声明

        2.块级作用域  只在块级作用域有效

        3.没有变量提升  

        4.不影响作用域链

    2.const 常量声明以及特性

      特性

        1.必须有初始值

        2.一般常量使用大写

        3.常量的值不能修改

        4.也是块级作用域

        5.对于数组和对象的修改,不算对常量的修改,不会报错(可以对数组和对象进行修改,指向的地址没有改变)

    3.变量的解构赋值

      1.数组的解构

        const RNG = ['uzi', 'mlxg', 'letme', 'ming']
        let [a, b, c, d] = RNG;// 每个值就是数组的位置对应的值

      2.对象的解构

      const UZI= {
        name: '自豪',
        age: 22,
        love: 'LOL',
        lol: function(){
          alert('打lol')
        }
      }
      let {name, age, love} = UZI;// 每个值是对象中对应的值
      let {lol} = UZI;
      lol();// 使用

    4.模板字符串  ``

      1.内容中可以直接出现换行符,单引号双引号内容不能直接用换行符(需要通过引号加号拼接)

        let str = `lol s10
          tes 是冠军`;// 可以这样直接使用换行符

      2.直接进行变量的拼接  ${}

        let lol = 'lol十周年';
        let uzi = `${lol} 中国队夺冠`

    5.对象的简写

      let name = 'zhangning187';
    
      let change = function(){
        console.log('努力改变');
      }
    
      const supwisdom = {
        name,
        change
      }

    6.箭头函数及声明特点  =>

      let fn = (a, b) => {
        return a + b;
      }
      fn(1, 2);// 3

      特点

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

        2.不能作为构造实例化对象

        3.不能使用arguments变量

        4.箭头函数的简写   

          let add = n => {
            return n*2;       }

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

          省略花括号,当代码体只有一条语句的时候,return 必须省略,语句的执行结果就是函数的返回值  

          let add = n => n*2; 

    7.函数参数的默认值

      1.形参初始值

        function add(a, b, c = 10) {// 当不传递c的时候,c的默认值是10,尽量把具有默认值的参数放在后面
          return a + b + c;
        }
        add (1, 2);// 13

      2.与解构赋值结合

        function con({name, age, love, height = '18'}) {// 还可以给默认值
          console.log(age);// 24
          console.log(height);// 没有传递,使用默认值 18
        }
        con({
          name: 'zhangning187',
          age: 24,
          love: 'js'
        })

    8.rest参数

      用于获取参数的实参,用于代替arguments

      rest参数是一个数组和es5中的arguments不一样,arguments里面是一个对象

      获取实参的方式

        function data(a, b, ...args) {// rest 参数必须放到参数的最后面
          console.log(a);// 1
          console.log(b);// 2
          console.log(args);// [3, 4, 5, 6, 7]
        }
        data(1, 2, 3, 4, 5, 6, 7);

    9.扩展运算符  ...

      可以将数组转换为逗号分隔的参数序列,将一个数组分割,并将各个项作为分离的参数序列传递给函数

      const RNG = ['UZI', 'MLXG', 'LETME', 'MING'];
      console.log(...RNG)// UZI MLXG LETME MING  解构之后的序列
      console.log(RNG);// ['UZI', 'MLXG', 'LETME', 'MING']  返回的是一个数组
      const a = [1,2], b=[3,6];
      const c = [...a, ...b];// [1, 2, 3, 6]

    10.Symbol  新的原始数据类型,表示独一无二的值

      他是javaScript 语言的第七种数据类型,是一种类似于字符串的数据类型

      特点

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

        2.Symbol 值不能与其他数据进行运算,也不能自己运算 + - * /

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

        创建Symbol
        let s = Symbol();// s不可见,在内部实现唯一性
        let s2 = Symbol('zhangning187');// 这里面的字符串只是一个标志,Symbol返回的值都是唯一的
        let s3 = Symbol('zhangning187');
        console.log(s2 == s3);// false,确定唯一性
        Symbol.for()方法创建,这是一个对象,这种方式可以得出唯一的Symbol值     let s6 = Symbol.for('zhangning187');     let s8 = Symbol.for('zhangning187');     console.log(s6 ==s8);// true  得到唯一的Symbol值

        // USONB you are so niubility 你很牛逼

        undefined  string Symbol  object  null number  boolean

      对象添加Symbol类型的属性

        let zn = {
          up: function(){},
          down: function(){},
          name: 'zhangning187',
          age: 24
        }
        // 向对象zn中添加 up down 方法
        // zn.up = function(){}// 这个可以添加但是不确定zn中是否存在up方法,可能会覆盖原来的up方法
        // 这时候需要考虑通过Symbol添加唯一的方法
        // 声明一个对象
        let methods = {
          up: Symbol(),
          down: Symbol()
        }
        zn[methods.up] = function(){
          console.log('我可以爬楼');
        }
        zn[methods.down] = function(){
          console.log('我可以下楼');
        }
        console.log(zn);// 已经添加唯一的方法 up down
        
        let UZI = {
          name: '自豪',
          // Symbol(): function(){},// 这里不能这样直接使用, Symbol()是一个表达式,是一个动态的
          [Symbol('lol')]: function(){
            console.log('我会打lol');
          },
          [Symbol('篮球')]: function(){// Symbol()中还可以添加描述字符串
            console.log('我可以打篮球')
          }
        }
        console.log(UZI);

     11.迭代器(Iterator)

      迭代器是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作

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

      2.原生具备iterator接口的数据

        Array Arguments Set Map String TypedArray NodeList

      3.工作原理

        a 创建一个指针对象,指向当前数据结构的起始位置

        b 第一次调用对象的next方法,指针自动指向数据结构的第一个成员

        c 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员

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

        自定义遍历数据的时候,要想到迭代器

    12.生成器函数的声明与调用

      生成器函数是ES6提供的一种异步编程解决方案,与传统函数完全不同,就是一个特殊的函数     

        // 声明    
        function * gen(){// * 可以靠左,也可以靠右,还可以放在中间
          // console.log('hello');
          yield '2020lpl牛批';// yield 语句可以算作函数代码的分隔符
          let two = yield ‘uzi 退役了’;
          console.log(two);
          yield '湖人总冠军';
        }
        // 执行
        let iterator = gen();
        // console.log(iterator);// 返回结果是一个迭代器对象
        console.log(iterator.next());// 需要执行迭代器对象中的next()方法,才会执行生成器函数
        console.log(iterator.next());// 每个next()只会执行里面一个yield语句,这个会输出 ‘uzi 退役了’
        // 传递参数 参数将作为上一个yield语句的返回结果
        console.log(iterator.next('AAA'));// 第三次调用传递的参数将作为第二个yield 的返回结果 打印为AAA
        // 使用for of循环遍历输出
        for(let v of gen()){
          console.log(v);// 依次输出yield语句中的值
        }

      案例:1s输出 111 2s输出 222 3s输出 333

        function one(){
          setTimeout(()=>{
            console.log('111')
            iterator.next();
          }, 1000)
        }
        function two(){
          setTimeout(()=>{
            console.log('222')
            iterator.next();
          }, 1000)
    
        }
        function three(){
          setTimeout(()=>{
            console.log('333')
          }, 1000)
    
        }
        // 生成器函数
        function * gen(){
          yield one();
          yield two();
          yield three();
        }
        // 调用生成器函数
        let iterator = gen();
        iterator.next();

    13.Promise 基本使用

      Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

        1 Promise 构造函数  Promise(excutor){}

        2 Promise.prototype.then  

          如果有一个参数,成功状态执行

          如果有两个参数,两个参数都是函数,成功状态(resolve())执行then中第一个函数,失败(reject())执行第二个函数

        3 Promise.prototype.catch(错误捕获)

          失败状态执行(reject())

        4 Promise.prototype.finally

          不管成功还是失败,都会执行,不接受任何参数,不依赖Promise执行结果

        5 Promise.all()  有许多个异步任务被同时触发,但你只想在它们都完成之后才做出回应

          传入一个 promise 的数组,然后在他们全部 resolve() 之后再执行回调函数

        6 Promise.race()  只要 promise 数组中有一个 promise 被 resolved 或者 rejected ,就执行

        7 Promise.none()  与 Promise.all 相反

          promise 数组全部 rejected() 才会执行

        8 Promise.any()  和 race() 有点不同,any() 表示 promise 数组中有一个 promise 被 resolved ,就执行

        9 Promise.first()  类似 race() ,只要有一个promise决议为 resolve ,就忽略后边的 promise

        // 实例化
        const p = new Promise((resolve, reject) => {
          // 通过resolve,reject这两个函数来改变Promise对象的状态,
          // resolve会改变p的状态为成功,reject会改变p的状态为失败,然后去执行then里面的方法
          // 执行异步操作,以定时器为例,定时器也是异步
          setTimeout(()=>{
            //let data = '异步执行成功';
            // resolve(data);// 调用resolve函数, p会变成一个成功的状态,会执行then中的第一个方法
            let err = '执行失败';
            reject(err);// 调用reject函数,p会变成一个失败的状态,会执行then中的第二个方法
          }, 1000)
        })
         // 成功会调用 promise 对象 then 方法
        p.then(value => {// 成功
          // console.log(value);// 控制台打印:异步执行成功
        }, reason => {// 失败
          console.error(reason)
        })

      Promise.prototype.then 特性 

        // then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
        const p = new Promise((resolve, reject) => {
          setTimeout(()=>{
            resolve('成功');
            reject('失败');
          }, 1000);
        });
        // then 的返回结果是一个Promise对象,就是result也是一个Promise对象,它的状态由函数的执行结果决定的
        const result  = p.then(value => {
          console.log(value);
          // 1.如果返回的结果是 非Promise 类型的属性,状态为成功,返回值return 中的值
          // 如果不写return,函数内部不写return返回结果是undefined,也不是Promise对象,状态也是成功
          // return 123;
          // 2.是 promise 对象, 该对象返回的状态就决定了then方法返回promise对象状态
          return new Promise((resolve, reject)=>{
            // resolve('ok');// then方法返回promise对象状态为成功
            reject('no');// then方法返回promise对象状态为失败
          })
          // 3.抛出错误  then方法返回promise对象状态为失败,错误值为抛出错误的值
          throw new Error('出错了');
        }, reason => {
          console.err(reason);
        });
        console.log(result);
        // 综上总结,then方法可以链式调用  可以改变回调域的现象
        p.then(value=>{}, reason=>{})
          .then(value()=>{}).then();

      举例:多个请求都返回之后,获取其中的数据(最好的方法是用 Promise.all() 方法)

        const p = new Promise((resolve, reject)=>{
          resolve('第一次返回成功')
        });
        p.then(value=>{
          return new Promise((resolve, reject)=>{
            resolve([value, '第二次返回成功'])
          });
        }).then(value=>{
          return new Promise((resolve, reject)=>{
            resolve([...value, '第三次返回成功'])
          });
        }).then(value=>{
          console.log(value);// 返回值为三次请求都返回成功以后的值
        });

        缺点:

          1.promise 一旦新建就会立即执行,无法中途取消

          2.当处于pending状态时,无法得知当前处于哪一个状态,无法得知是刚刚开始还是刚刚结束

          3.如果不设置回调函数,promise内部的错误就无法反映到外部

          4.promise封装函数请求的时候,由于promise是异步任务,发送请求的三步会被延后到整个脚本同步代码执行完,并且将响应回调函数延迟到现有队列的最后,如果大量使用会大大降低请求效率

    14.集合set

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

      集合的属性和方法

        1 size  返回集合的元素个数

        2 add  添加一个新元素,返回当前集合

        3 delete  删除元素,返回boolean值

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

        5 clear  清空

        // 声明
        let s = new Set();
        let s2 = new Set([1, 2, 3, 6, 7]);
        console.log(s2);// 5
        s2.add(8);// 添加新元素 
        console.log(s2);// 输出 {1, 2, 3, 6, 7, 8}
        s2.delete(8);
        console.log(s2);// 输出 {1, 2, 3, 6, 7}
        console.log(s2.has(8));// false
        // s2.clear();// 清空
    
        let arr = [1, 2, 3, 3, 3, 6, 6, 8];
        let arr2 = [1, 3, 6, 7, 8];
        // 数组去重
        let result = [...new Set(arr)];
        // 交集
        let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
        // 并集
        let result = [...new Set([...arr, ...arr2])];
        // 差集 arr有arr2中没有
        let result = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));

    15.Map集合

      类似于对象,也是键值对的集合,但是 键 不限于字符串,各种类型的值(包括对象)都可以当作键,

       map也实现了 iterator 接口,所以可以使用扩展运算符和for of进行遍历

        1 size  返回 Map 的元素个数

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

        3 get  返回键名对象的键值

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

        5 clear  清空集合,返回undefined

        // 声明
        let m = new Map();
        m.set('name', 'zhangning');
        m.set('change', function(){console.log('变得更努力')});// 键 change 值 一个function
        let key = {company: 'supwisdom'}; 
        m.set(key, [1, 2, 3]);//键 对象 值 数组
        m.size;// 获取m个数
        m.delete('name');// 删除键值对
        m.get('change');// 获取键对应的值
        // m.clear();// 清空
        for(let v of m){console.log(v);}

    16.class 类

      通过class可以定义类,新的class写法只是让对象原型的写法更加清晰,更像面向对象编程的语法而已。

        1 class  声明类

        2 constructor  定义构造函数初始化

        3 extends  继承父类

        4 super  调用父级构造方法

        5 static  定义静态方法和属性

        6 父类方法可以重写

         // es5通过 构造函数实例化 对象的方法

        //
        function People(name, sex) {
          this.name = name;
          this.sex = sex;
        }
        // 这个height这种添加方式是属于函数对象的,不属于实例对象,这样的属性称之为静态成员
        People.height = '180';
        People.prototype.height1 = '100';
        // 添加方法
        People.prototype.play = function(){
          console.log('打篮球');
        }
        let zn = new People('zhangning', '男');
        zn.play();// 输出 打篮球
        console.log(zn);
        console.log(zn.height);// 输出 undefined 
        console.log(zn.height1);// 输出 100,必须通过prototype添加才能添加到实例对象上

      通过class实现

        class People{
          // 静态属性 static,对于static 标注的方法属于类,不属于实例对象
          static height = '100';
          static change(){
            console.log('我可以改变世界');
          }
          // 构造方法 名字不能更改(在使用new People的时候会自动执行实例对象上的constructor方法)       
          constructor(name, sex){
            this.name = name;
            this.sex = sex;
          }
          // 添加方法必须使用该语法,不能使用es5的完整形式(play: function(){} 这种形式不支持,必须使用play()形式)
          // 成员属性
          play(){
            console.log('打篮球');
          }
        }
        let zn = new People('zhangning', '男');
        console.log(zn);
        console.log(zn.height);// undefined  static 标注的方法属于类,不属于实例对象
        console.log(People.height);// 100  

      使用es5构造函数实现继承  

        // 举例 chinese 继承 People 属性
        function People(name, sex) {
          this.name = name;
          this.sex = sex;
        }
        People.prototype.play = function(){
          console.log('打LOL');
        }
        function Student(name, sex, like, height){
          // 通过call方法,改变this值,this指向chinese中的this,也就是chinese的一个实例对象
          People.call(this, name, sex);
          this.like = like;
          this.height = height;
        }
        // 设置子集构造函数原型
        Student.prototype = new People;// 这样就会有父级的一个方法
        Student.prototype.constructor = Student;// 做一个校正,没有这行代码也无所谓
        // 声明子类方法
        Student.prototype.photo = function(){
          console.log('去拍照');
        }
        // 实例化
        const zn = new Student('zhangning', '男', '打篮球', '187');
        console.log(zn)

      使用es6 class 类 实现继承 及 父类方法的重写

        // 声明父类
        class People{
          // 父类构造方法
          constructor(name, sex) {
            this.name = name;
            this.sex = sex;
          }
          // 父类成员属性
          play(){
            console.log('打LOL');
          }
        }
        // 声明子类 使用extends 继承父类
        class Student extends People {
          // 构造方法
          constructor(name, sex, like, height){
            super(name, sex);// super 就是父类的constructor构造函数,这样调用
            this.like = like;
            this.height = height;
          }
          photo(){
            console.log('去拍照');
          }
          // 对父类中的play方法进行重写,子类是不能去调用父类的同名方法的,
    
          play(){
            // super(); 不允许,在普通的成员方法里面是不能出现super()去调用父类的同名方法的,会报错,只能完全重写
            console.log('我会打LOL,还会打篮球');
          }
        }
        const zn = new Student('zhangning', '男', '打篮球', '187');
        console.log(zn)

      class 中 getter 和 setter 设置

        class People{
          get like(){
            return '打篮球';
          }
          set like(newVal){
            // 通过传过来的newVal值,进行操作,改变 like
            console.log('改变like值');
          }
        }
        let p = new People();
        console.log(p.like)// 输出 打篮球
        p.like = 'LOL';// 然后通过 set like 进行操作

    17.对象数值扩展

      1 Object.is  判断两个值是否完全相等

        Object.is(1, 1);// true

        和 === 很相似,唯一区别就是 NaN === NaN 为 false, Object.is(NaN, NaN) 为true

      2 Object.assign  对象的合并

        const c1 = {name: 'znn'};
        const c2 = {name: 'zhangning', height: 187};
        Object.assign(c1, c2);// 如果两个对象中存在相同属性,c2 中覆盖c1中的属性内容

      3 Object.setPrototypeOf  设置原型对象

        const zn = {
          name: 'zhangning',
        }
        const p = {
          h: true,
          sfsfdf: 'fasfasdf'
        }
        Object.setPrototypeOf(zn, p);// 设置 zn 的原型里面有 p
        Object.getPrototypeOf(zn);// 获取 zn 的原型
        console.log(zn);// 打印看下
  • 相关阅读:
    学生免费注册Pycharm
    CSS笔记
    加载CIFAR数据集时报错的大坑
    发布小程序
    微信中的动图如果发朋友圈
    安卓第一个小项目
    转换小写字母
    1小时搞定vuepress快速制作vue文档/博客+免费部署预览
    干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)
    JavaScript 加减危机——为什么会出现这样的结果?
  • 原文地址:https://www.cnblogs.com/zhangning187/p/es6zjzn.html
Copyright © 2011-2022 走看看