es6~now新特性

本文最后更新于:2022年3月30日 下午

Javascript = Web Api + ECMAScript

ES2015 后都使用年份做版本

【let / const】

  • 都用于声明变量
  • 不存在变量提升,暂时性死区
  • 不能重复声明
  • 块级作用域 []

let

  • 可以重新赋值

    const

  • 声明时需赋值
  • 只读不可改变(对于复杂变量,可以修改变量内容,变量内存地址未改变)

【解构赋值】

只有可遍历(具备遍历器[Symbol.Iterator])的数据结构才能解构赋值

用途

  • 交换变量

  • 提取对象中的数据

  • 解构默认值

  • 剩余运算符...

  • 数组结构 const [a,b,c] = [1,2,3]

  • 对象结构

    const obj = {name:'xxx',age:14}
    const {name,age} = obj
    // 别名
    const {name:trueName} = obj
    console.log(trueName)

【字符串】

  • 方法
    • includes()
    • startsWith()
    • endsWith()
    • padStart(len,x)// 补全后的最小长度,不足则用x在开头填充
    • padEnd()// 在末尾填充
    • repeat()// 重复
  • 模版字符串
    • 多行
    • 插值${x}

【数值】

普通number类型只能保留53个二进制位/16个10进制位的精度

  • 最大最小安全整数Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER
  • 识别
    • Number.isSafeInteger()
    • Number.isFinite()
  • 大数BigInt类型,后要加上字母n123n,没有位数限制
  • 指数运算**

【数组】

  • 方法
    Array.from() // 从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
    Array.of() // Array()只传一个参数就作为新建的数组长度
    includes()
    copyWithin()
    fill()
    find() / findIndex()
    keys(),values(),entries()
    flat()
  • 扩展运算符...

【对象】

  • 方法
    Object.is(a,b)// 比较两个值是否严格相等,与(===)基本类似
    // Object.is与全等的区别
    //  Object.is(+0,-0);  //false
    //  +0 === -0  //true
    
    //  Object.is(NaN,NaN); //true
    //  NaN === NaN  //false
    Object.assign() // 潜拷贝
  • 扩展运算符...

【函数】

  • 箭头函数
    • 箭头函数没有自己的this,静态绑定书写时的上下文
    • 箭头函数没有prototype —> 不能作为构造函数,不能 new
    • 箭头函数没有arguments属性
    • 不能用作generator函数
  • 函数参数默认值function fn1(arg1='xxx'){}
  • 函数剩余参数function(a, b, ...theArgs)

【Symbol】

独一无二的值,Symbol()声明不需要new

  • 作为不变的常量

    const FLAG1 = Symbol()
    const FLAG2 = Symbol()
  • 私有变量

    const obj1 = (() => {
      let var1 = symbol('var1')
      class Inner{
        constructor(){
          this[var1] = 'abcde'
        }
        getVar(){
          return this[var1]
        }
      }
      return Inner
    })()
    const o1 = obj1()
    console.log(o1)
    // {Symbol(var1):'abcde'}
    // 不能直接访问

    【Set/WeakSet】

  • Set类似于数组,但是成员的值都是唯一的,拥有迭代器

    size
    add()
    delete()
    has()
    clear()
  • WeakSet的成员只能是对象,【弱引用】,【不可遍历】

    add()
    delete()
    has()

【Map/WeakMap】

  • Object的键传统上只能使用字符串,Map无此限制,拥有迭代器
    size
    set(key,value) // 返回整个 Map 结构
    get() // 找不到该 key 返回 undefined
    has()
    delete() // 删除失败返回 false
    clear() // 无返回值
  • WeakMap只接受对象作为键名(除了null),【键名弱引用】
    set()
    get()
    has()
    delete()
  • map和object的区别
    1. 键的变量类型限制
    2. map原生具有遍历器
    3. map遍历时保持插入时的顺序(object遍历时会对整数键名排序)
    4. map.size()返回长度

【Proxy】

拦截器/代理 const _proxy1 = new Proxy(target,handler)

// 常用handlers
getPrototypeOf()
// Object.getPrototypeOf 方法的捕捉器。
setPrototypeOf()
// Object.setPrototypeOf 方法的捕捉器。
getOwnPropertyDescriptor()
// Object.getOwnPropertyDescriptor 方法的捕捉器。
defineProperty()
// Object.defineProperty 方法的捕捉器。
has()
// in 操作符的捕捉器。
get()
// 属性读取操作的捕捉器。
set()
// 属性设置操作的捕捉器。
deleteProperty()
// delete 操作符的捕捉器。
ownKeys()
// Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
apply()
// 函数调用操作的捕捉器。
construct()
// new 操作符的捕捉器。

【Reflect】

操作对象的API

  • 对象操作能返回布尔值
  • 将对象操作函数化

    某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

  • 与Proxy中方法均对应

    【Promise】

  • 处理异步操作,避免回调嵌套
  • 状态不可逆
  • 中途不可停止
  • 需要捕获promise内错误
new Promise((resolve,reject))
Promise.prototype.then(onFulfilled,onRejected)
Promise.prototype.catch()
// promise中的错误会一直冒泡到最后,没有捕获则报错
Promise.prototype.finally()
Promise.all() // 全部fulfilled或者有谁rejected
Promise.allSettled() // 全部得到不管什么状态
Promise.race() // 最先改变status
Promise.any() // 最先fulfilled或者全部rejected
Promise.resolve()
Promise.reject()
Promise.try()

【Iterator迭代器】

[Symbol.Iterator]

  • 统一的遍历集合数据的借口
  • 只要拥有[Symbol.Iterator]的数据结构都可以用for…of遍历

原生具备 Iterator 接口的数据结构如下。

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments
  • Dom Node

【Generator】

  • 调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器 ( iterator )对象。
  • 当这个迭代器的 next() 方法被调用时返回一个对象,{value:当前的返回,done:是否迭代完},其内的语句会执行到下一个yield的位置,yield 后紧跟迭代器要返回的值。
  • 或者如果用的是 yield*,则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。
  • 当在生成器函数中显式 return 时,会导致生成器立即变为完成状态,如果 return 后面跟了一个值,那么这个值会作为当前调用 next() 方法返回值。
  • 调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量,例如下面例子中的 x :
    function *gen(){
        yield 10;
        x=yield 'foo';
        yield x;
    }
    
    var gen_obj=gen();
    console.log(gen_obj.next());// 执行 yield 10,返回 10
    console.log(gen_obj.next());// 执行 yield 'foo',返回 'foo'
    console.log(gen_obj.next(100));// 将 100 赋给上一条 yield 'foo' 的左值,即执行 x=100,返回 100
    console.log(gen_obj.next());// 执行完毕,value 为 undefined,done 为 true

【async/await】

自执行的Generator函数语法糖。

【Class】

  1. 类表达式和类声明

    let A = class {
    
    }
    // or
    class A {
    
    }

    类声明和类表达式的主体都执行在严格模式下

  2. 继承

    本质使用的是原型式继承

    class B{
      constructor(name){
        this.name = name
      }
    
      fun1(){}
    }
    
    class A extend B{
      constructor (name){
        super(name) // 调用父类构造函数 // 
      }
    
      fun2(){
        super.fun1() // 调用一个父类方法
      }
    }
    
  3. 静态字段,私有字段,私有实例字段

    class Example{
      //静态字段
      static attr1 = 123
      static func1(){return 'im func1'}
      //只在类声明中存在,实例不能访问
    
      // 公有字段
      attr2 = 666
      func2(){}
      // 每个实例都复制一份
    
      //私有实例字段
      //不能直接访问,闭包访问
      #attr3
      constructor(name){
        this.#attr3 = name
      }
      getPrivate(){
        return this.#attr3
      }
      #func3 = () =>{
        return console.log('im private');
      }
      getPrivateFunc(){
        return this.#func3()
      }
    }
  4. getter / setter

    当使用 get 关键字时,属性将被定义在实例的原型上,当使用Object.defineProperty()时,属性将被定义在实例自身上。

    class Example {
      get hello() {
        return 'world';
      }
    }
    
    const obj = new Example();
    console.log(obj.hello);
    // "world"
    
    console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
    // undefined

    【模块化 ES module】

  5. 语法

export / export

// 这是 Node 中向外暴露成员的形式:
// module.exports = {}

// ES6中导入模块,使用 import 模块名称 from '模块标识符' import '表示路径'
// 在 ES6 中,使用 export default 和 export 向外暴露成员:
var info = {
  name: "zs",
  age: 20
};
export default info;

export default {
  address: "深圳"
};
// 注意: export default 向外暴露的成员,可以使用任意的变量来接收
// 注意: 在一个模块中,export default 只允许向外暴露1次
// 注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员

export var title = "小星星";
export var content = "哈哈哈";
// 注意: 使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做 【按需导出】
// 注意: export 可以向外暴露多个成员, 同时,如果某些成员,我们在 import 的时候,不需要,则可以不在 {} 中定义
// 注意: 使用 export 导出的成员,必须严格按照 导出时候的名称,来使用 {} 按需接收;
// 注意: 使用 export 导出的成员,如果 就想 换个 名称来接收,可以使用 as 来起别名;

// 在Node中 使用 var 名称 = require('模块标识符')
// module.exports 和 exports 来暴露成员
  1. 使用 babel 编译 ES6 语法

    Babel 是一个工具链,主要用于在旧的浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容版本的 JavaScript 代码

  2. 模块化工具 webpack,rollup

装饰器语法

@demo
class MyClass{}

function demo(target){
  target.value = 666
}

// 等价于
MyClass = demo(MyClass)

es6~now新特性
http://yoursite.com/2022/02/24/es6新特性/
作者
tatekii
发布于
2022年2月24日
许可协议