zoukankan      html  css  js  c++  java
  • 总结部分常用ES6的语法及其简单解析

    let/const

    let/const用于声明变量,替代老语法的var关键字,它的用法与var类似,但是所声明的变量只在所在的代码块中有效。

    let/constvar的主要区别:

    • 不允许重复声明
    • 未定义就使用会报错:let/const不存在变量提升现象
    • 暂时性死区:在代码块内使用const命令let命令声明变量之前,该变量都不可用

    const

    let不相同的是,const声明的是一个只读常量。

    const的特点:

    • constlet不同,const声明后必须立马赋值,只声明不赋值就会报错
    • const是一个只读常量,并不是变量的值不改变,而是变量指向的那个内存地址不改变。
      • 对于简单类型的数据(数值、字符串、布尔值),就相当于常量
      • 对于复合类型的数据(数组、对象),变量指向内存地址,const实际保存的是指向实际数据的指针,它只能保证指针不变,不能保证,指针里的内容不变,

    解构赋值

    多种解构

    字符串解构

    字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

    const [a, b, c, d, e] = 'hello';
    

    数值和布尔值解构

    解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

    let {toString: s} = 123;
    s === Number.prototype.toString // true
    
    let {toString: s} = true;
    s === Boolean.prototype.toString // true
    

    对象解构

    对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    形式:const { x, y } = { x: 1, y: 2 }

    默认:const { x, y = 2 } = { x: 1 }

    改名:const { x, y: z } = { x: 1, y: 2 }

    数组解构

    只要某种数据结构具有Iterator接口就可采用数组形式的解构赋值

    形式:const [x, y] = [1, 2]

    默认:const [x, y = 2] = [1]

    函数参数解构

    //数组参数解构
    function add([x, y]){
      return x + y;
    }
    
    add([1, 2]); // 3
    
    //对象参数解构且有默认值
    function move({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, 0]
    move({}); // [0, 0]
    move(); // [0, 0]
    

    应用场景

    • 交换变量值:[x, y] = [y, x]

    • 返回函数多个值:const [x, y, z] = Func()

    • 定义函数参数:Func([1, 2])

    • 提取JSON数据:const { name, version } = packageJson

    • 定义函数参数默认值:function Func({ x = 1, y = 2 } = {}) {}

    • 遍历Map结构:for (let [k, v] of Map) {}

    • 输入模块指定属性和方法:const { readFile, writeFile } = require("fs")

    重点

    • 匹配模式:只要等号两边的模式相同,左边的变量就可以赋给右边
    • 解构赋值规则:只要右边不是对象或者数组,就会将其转换为对象
    • 解构不成功时,变量的值为undifined
    • undifinednull无法转为对象,因此无法赋值

    箭头函数

    ES6 允许使用箭头(=>)定义函数,简化定义函数

    var f = v => v;
    
    // 等同于
    var f = function (v) {
      return v;
    };
    
    • 无参数:() => {}
    • 单个参数:x => {}
    • 多个参数:(x, y) => {}
    • 解构参数:({x, y}) => {}

    重点

    • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

    • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

    • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    数组的扩展

    扩展运算符(...):转换数组为用逗号分隔的参数序列([...arr],相当于rest/spread参数的逆运算)

    Array.from():转换具有Iterator接口的数据结构为真正数组,返回新数组

    类数组对象:包含length的对象Arguments对象NodeList对象

    可遍历对象:StringSet结构Map结构Generator函数

    Array.of():转换一组值为真正数组,返回新数组

    copyWithin():把指定位置的成员复制到其他位置,返回原数组

    find():返回第一个符合条件的成员

    findIndex():返回第一个符合条件的成员索引值

    fill():根据指定值填充整个数组,返回原数组

    keys():返回以索引值为遍历器的对象

    values():返回以属性值为遍历器的对象

    entries():返回以索引值和属性值为遍历器的对象

    数组空位:ES6明确将数组空位转为undefined(空位处理规不一,建议避免出现)

    扩展运算符的应用

    克隆数组:const arr = [...arr1]

    合并数组:const arr = [...arr1, ...arr2]

    拼接数组:arr.push(...arr1)

    代替apply:Math.max.apply(null, [x, y]) => Math.max(...[x, y])

    转换字符串为数组:[..."hello"]

    转换类数组对象为数组:[...Arguments, ...NodeList]

    转换可遍历对象为数组:[...String, ...Set, ...Map, ...Generator]

    与数组解构赋值结合:const [x, ...rest/spread] = [1, 2, 3]

    计算Unicode字符长度:Array.from("hello").length => [..."hello"].length

    Set

    • 定义:类似于数组的数据结构,成员值都是唯一且没有重复的值
    • 声明:const set = new Set(arr)
    • 入参:具有Iterator接口的数据结构
    • 属性
      • constructor:构造函数,返回Set
      • size:返回实例成员总数
    • 方法
      • add():添加值,返回实例
      • delete():删除值,返回布尔
      • has():检查值,返回布尔
      • clear():清除所有成员
      • keys():返回以属性值为遍历器的对象
      • values():返回以属性值为遍历器的对象
      • entries():返回以属性值和属性值为遍历器的对象
      • forEach():使用回调函数遍历每个成员

    应用场景

    • 去重字符串:[...new Set(str)].join("")
    • 去重数组:[...new Set(arr)]Array.from(new Set(arr))
    • 集合数组
      • 声明:const a = new Set(arr1)const b = new Set(arr2)
      • 并集:new Set([...a, ...b])
      • 交集:new Set([...a].filter(v => b.has(v)))
      • 差集:new Set([...a].filter(v => !b.has(v)))
    • 映射集合
      • 声明:let set = new Set(arr)
      • 映射:set = new Set([...set].map(v => v * 2))set = new Set(Array.from(set, v => v * 2))

    重点难点

    • 遍历顺序:插入顺序
    • 没有键只有值,可认为键和值两值相等
    • 添加多个NaN时,只会存在一个NaN
    • 添加相同的对象时,会认为是不同的对象
    • 添加值时不会发生类型转换(5 !== "5")
    • keys()values()的行为完全一致,entries()返回的遍历器同时包括键和值且两值相等

    WeakSet

    • 定义:和Set结构类似,成员值只能是对象
    • 声明:const set = new WeakSet(arr)
    • 入参:具有Iterator接口的数据结构
    • 属性
      • constructor:构造函数,返回WeakSet
    • 方法
      • add():添加值,返回实例
      • delete():删除值,返回布尔
      • has():检查值,返回布尔

    应用场景

    • 储存DOM节点:DOM节点被移除时自动释放此成员,不用担心这些节点从文档移除时会引发内存泄漏
    • 临时存放一组对象或存放跟对象绑定的信息:只要这些对象在外部消失,它在WeakSet结构中的引用就会自动消

    重点难点

    • 成员都是弱引用,垃圾回收机制不考虑WeakSet结构对此成员的引用
    • 成员不适合引用,它会随时消失,因此ES6规定WeakSet结构不可遍历
    • 其他对象不再引用成员时,垃圾回收机制会自动回收此成员所占用的内存,不考虑此成员是否还存在于WeakSet结构

    Map

    • 定义:类似于对象的数据结构,成员键是任何类型的值
    • 声明:const set = new Map(arr)
    • 入参:具有Iterator接口且每个成员都是一个双元素数组的数据结构
    • 属性
      • constructor:构造函数,返回Map
      • size:返回实例成员总数
    • 方法
      • get():返回键值对
      • set():添加键值对,返回实例
      • delete():删除键值对,返回布尔
      • has():检查键值对,返回布尔
      • clear():清除所有成员
      • keys():返回以键为遍历器的对象
      • values():返回以值为遍历器的对象
      • entries():返回以键和值为遍历器的对象
      • forEach():使用回调函数遍历每个成员

    重点难点

    • 遍历顺序:插入顺序
    • 对同一个键多次赋值,后面的值将覆盖前面的值
    • 对同一个对象的引用,被视为一个键
    • 对同样值的两个实例,被视为两个键
    • 键跟内存地址绑定,只要内存地址不一样就视为两个键
    • 添加多个以NaN作为键时,只会存在一个以NaN作为键的值
    • Object结构提供字符串—值的对应,Map结构提供值—值的对应

    WeakMap

    • 定义:和Map结构类似,成员键只能是对象
    • 声明:const set = new WeakMap(arr)
    • 入参:具有Iterator接口且每个成员都是一个双元素数组的数据结构
    • 属性
      • constructor:构造函数,返回WeakMap
    • 方法
      • get():返回键值对
      • set():添加键值对,返回实例
      • delete():删除键值对,返回布尔
      • has():检查键值对,返回布尔

    应用场景

    • 储存DOM节点:DOM节点被移除时自动释放此成员键,不用担心这些节点从文档移除时会引发内存泄漏
    • 部署私有属性:内部属性是实例的弱引用,删除实例时它们也随之消失,不会造成内存泄漏

    重点难点

    • 成员键都是弱引用,垃圾回收机制不考虑WeakMap结构对此成员键的引用
    • 成员键不适合引用,它会随时消失,因此ES6规定WeakMap结构不可遍历
    • 其他对象不再引用成员键时,垃圾回收机制会自动回收此成员所占用的内存,不考虑此成员是否还存在于WeakMap结构
    • 一旦不再需要,成员会自动消失,不用手动删除引用
    • 弱引用的只是键而不是值,值依然是正常引用
    • 即使在外部消除了成员键的引用,内部的成员值依然存在

    Promise

    • 定义:Promise是一种异步编程的解决方案。从语法上来讲,Promise是一个对象,他可以获取异步操作的的消息。从本意上来讲,Promise是一个承诺,承诺过一段时间后给你一个结果。Promise有三种状态:pending(等待),fulfiled(成功),rejected(失败),状态一旦改变,就不会再变。
    • 状态:
      • 进行中:pending
      • 已成功:fulfilled
      • 已失败:rejected
    • 特点:
      • 对象的操作不受外界的影响
      • 一旦状态改变,任何时候都会得到这个结果
    • 示例:
    const promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    • 出参

      • resolve:将状态从未完成变为成功,在异步操作成功时调用,并将异步操作的结果作为参数传递出去
      • reject:将状态从未完成变为失败,在异步操作失败时调用,并将异步操作的错误作为参数传递出去
    • 方法:

      • then():分别指定resolvedrejected状态的回调函数

        • 第一参数:状态变为resolved时调用
        • 第二参数:状态变为rejected时调用
      • catch():用于指定发生错误时的回调函数。

      • Promise.all():将多个实例包装成一个新实例,返回全部实例状态变更后的结果数组(齐变更再返回)

        • 入参:具有Iterator接口的数据结构
        • 成功:只有全部实例状态变成fulfilled,最终状态才会变成fulfilled
        • 失败:其中一个实例状态变成rejected,最终状态就会变成rejected
      • Promise.race():将多个实例包装成一个新实例,返回全部实例状态优先变更后的结果(先变更先返回)

        • 入参:具有Iterator接口的数据结构
        • 成功失败:哪个实例率先改变状态就返回哪个实例的状态
      • Promise.resolve():将对象转为Promise对象(等价于new Promise(resolve => resolve()))

        • Promise实例:原封不动地返回入参
        • Thenable对象:将此对象转为Promise对象并返回(Thenable为包含then()的对象,执行then()相当于执行此对象的then())
        • 不具有then()的对象:将此对象转为Promise对象并返回,状态为resolved
        • 不带参数:返回Promise对象,状态为resolved
      • Promise.reject():将对象转为状态为rejected的Promise对象(等价于new Promise((resolve, reject) => reject()))

    应用场景

    • 加载图片

    • AJAX转Promise对象

    重点难点

    • 只有异步操作的结果可决定当前状态是哪一种,其他操作都无法改变这个状态

    • 状态改变只有两种可能:从pending变为resolved、从pending变为rejected

    • 一旦新建Promise对象就会立即执行,无法中途取消

    • 不设置回调函数,内部抛错不会反应到外部

    • 当处于pending时,无法得知目前进展到哪一个阶段

    • 实例状态变为resolvedrejected时,会触发then()绑定的回调函数

    • resolve()reject()的执行总是晚于本轮循环的同步任务

    • then()返回新实例,其后可再调用另一个then()

    • then()运行中抛出错误会被catch()捕获

    • reject()的作用等同于抛出错误

    • 实例状态已变成resolved时,再抛出错误是无效的,不会被捕获,等于没有抛出

    • 实例状态的错误具有冒泡性质,会一直向后传递直到被捕获为止,错误总是会被下一个catch()捕获

    • 不要在then()里定义rejected状态的回调函数(不使用其第二参数)

    • 建议使用catch()捕获错误,不要使用then()第二个参数捕获

    • 没有使用catch()捕获错误,实例抛错不会传递到外层代码,即不会有任何反应

    • 作为参数的实例定义了catch(),一旦被rejected并不会触发Promise.all()catch()

    • Promise.reject()的参数会原封不动地作为rejected的理由,变成后续方法的参数

    for...of循环

    • 定义:调用Iterator接口产生遍历器对象(for-of内部调用数据结构的Symbol.iterator())

    • 遍历字符串for-in获取索引for-of获取.

    • 遍历数组for-in获取索引for-of获取

    • 遍历Setfor-of获取 => for (const v of set)

    • 遍历Mapfor-of获取键值对 => for (const [k, v] of map)for-of获得到的是一个由构成的数组

      let map = new Map().set('a', 1).set('b', 2);
      for (let pair of map) {
        console.log(pair);
      }
      // ['a', 1]
      // ['b', 2]
      
      for (let [key, value] of map) {
        console.log(key + ' : ' + value);
      }
      // a : 1
      // b : 2
      
    • 遍历对象for-in获取for-of需自行部署for-of并不能直接遍历对象,如果直接遍历会报错。我们需要部署Iterator接口。遍历对象还是使用for-in更好一点

      1. 使用Object.keys方法将对象的键名生成一个数组,然后遍历这个数组。
      for (var key of Object.keys(someObject)) {
        console.log(key + ': ' + someObject[key]);
      }
      
      1. 使用 Generator 函数将对象重新包装一下。
      function* entries(obj) {
        for (let key of Object.keys(obj)) {
          yield [key, obj[key]];
        }
      }
      
      for (let [key, value] of entries(obj)) {
        console.log(key, '->', value);
      }
      // a -> 1
      // b -> 2
      // c -> 3
      
    • for-in区别

      • 有着同for-in一样的简洁语法,但不会像for-in一样会遍历原型上的属性。
      • for-of会以添加顺序来进行遍历,而不会像for-in以任意顺序遍历
      • 不同于forEach(),它可与breakcontinuereturn配合使用
      • 提供遍历所有数据结构的统一操作接口

    搬运文章

    ES6入门教程

    Promise不会??看这里!!!史上最通俗易懂的Promise!!!

    近一万字的ES6语法知识点补充

  • 相关阅读:
    LIst判断是否为空
    SYBASE数据库基本操作
    Java内部类详解--成员内部类,局部内部类,匿名内部类,静态内部类
    String转jsonarry:字符串:[{"result":"20"},{"result":"21"},{"result":"20"},{"result":"22"}]
    使用HttpURLConnection发送POST请求
    Java 定义字符串数组
    JSP 解决illegal to have multiple occurrences of contentType with different values错误
    javascript 获取url参数值
    外键为','(逗号)拼接ID,连接查询外键表ID
    excel、csv、txt文件数据读取
  • 原文地址:https://www.cnblogs.com/chuncode/p/13489632.html
Copyright © 2011-2022 走看看