读书笔记(六):ES Next

本文介绍了ES Next的新特性,包括Array.prototype.includes、Object.spread与Object.assign的区别、箭头函数的限制以及proxy、assert和decorator的应用。同时,讨论了Babel如何通过AST转换代码以解决兼容性问题,如const、let的处理以及箭头函数中this的绑定策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.新特性实例

  • includes

    Array.prototype.includes用来判断数组是否包含某个元素的,Array.prototype.indexOf采用了===进行比较,而includes采用了SameValueZero()进行比较,这是引擎内置的比较方式,没有对外接口,其实现采用了Map和Set,最直接的好处就是可以判断NaN。

    [NaN].includes(NaN) // true
    [NaN].indexOf(NaN) // -1
    
  • Object.spread和Object.assign

    {…obj}和Object.assign({}, obj)是等价的,但是还存在区别。Object.assign会修改第一个参数对象,这个修改可以触发其第一个参数对象的settter。Object.spread会创建一个对象副本,而不会修改任何值。虽然保证assign第一个参数为空对象,也能实现同样的不可变性,但性能相对差很多。

  • 箭头函数不适用场景

    构造函数的原型方法需要通过this获得实例,因此箭头函数不可以出现在构造函数的原型方法上。

    const person = {
      name: 'jack',
      getName: () => {
        console.log(this.name)
      }
    }
    person.getName()
    

    getName函数内的this指向window,并不符合使用场景。

    const btn = document.getElementById('btn')
    btn.addEventListener('click', () => {
      console.log(this === window)
    })
    

    事件绑定函数内的this指向了window,无法获取事件对象。

  • proxy代理

    class Person {
      constructor(name) {
      this.name = name
      }
    }
    
    let proxyPerson  = new Proxy(Person, {
      apply(target, context, args) {
        throw new Error('error')
      }
    })
    

    对Person构造函数进行了代理,防止它作为非构造函数被调用。

      proxyPerson('jack') // Uncaught Error
      new proxyPerson('jack') // {name: 'jack'}
    

    也可以改造成不使用new关键字调用:

    let proxyPerson  = new Proxy(Person, {
      apply(target, context, args) {
        return new (target.bind(context, ...args))()
      }
    })
    
  • assert断言

    assert['error msg'] = boolean
    

    当右侧表达式不成立时,抛出错误。
    可以通过拦截assert对象的赋值操作实现:

    const assert = new Proxy({}, {
      set(target, warning, value) {
        if (!value) {
          console.log(warning)
        }
      }
    })
    
  • decorator装饰器
    装饰器就是给类添加或修改属性与方法的。
    在对象方法中给普通函数赋值后,在全局作用域下被调用时this指向会丢失,指向了window,可以使用autobind完成对this的绑定。

    class Person {
      constructor(name) {
        this.name = name
      }
      @autobind
      getName() {
        return this.name
      }
    }
    

2.babel编译
babel最核心的功能是:编译ES Next代码,进行降级处理,进而规避兼容性问题。核心原理是使用AST(抽象语法树)对源码进行分析并转为目标代码。

  • const、let都会被编译为var,babel在编译过程中发现对const声明的变量二次赋值会直接报错。对块级作用域,在块内给变量换一个名字,这样在块外自然无法被访问到了。

  • 对于for循环,babel使用闭包来储存变量。

  • 箭头函数中会将当前环境下的this保存为新的变量,在调用方法时用新存储的this替换函数体内的this。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值