ES6 babel原理、let,const,var的区别

362 阅读4分钟

babel原理(ES6转化为ES5)

转换过程

  • Parser 解析

第一步主要是将 ES6 语法解析为 AST 抽象语法树。简单地说就是将代码打散成颗粒组装的对象。这一步主要是通过 babylon 插件来完成。

  • Transformer 转换

第二步是将打散的 AST 语法通过配置好的 plugins(babel-traverse 对 AST 进行遍历转译)和 presets 转换成新的 AST 语法。这一步主要是由 babel-transform 插件完成。plugins 和 presets 通常在 .babelrc 文件中配置。

  • Generator 生成

第三步是将新的 AST 语法树对象再生成浏览器都可以识别的 ES5 语法。这一步主要是由 babel-generator 插件完成。

简单描述:

ES6代码输入=====》 babylon(babel的语法解析器)进行解析====》得到AST(抽象语法树)=====》plugin用babel-traverse对AST树进行遍历转译=====》得到新的AST树=====》用babel-gennerator通过AST树生成ES5代码

var、let、const

背景:ES5中的变量只有全局作用域和函数作用域,某些场景会出现下列问题:

  • 内层变量会覆盖外层变量
var a = 'test'
function f(){
   console.log(a) // undefined,(变量提升,函数内的覆盖到外层的变量)
   var a = 'ES6'
}
f()
  • 用于计数的循环(for循环)变量泄露为全局变量 let,const声明的变量为块级作用域,可解决上述问题
三者的区别:
  • 变量提升
    • var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
    • let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
  • 暂时性死区
    • var不存在暂时性死区
    • let和const存在暂时性死区,只有等到声明变量的哪一行代码出现,才可以获取和使用该变量
  • 块级作用域
    • var不存在块级作用域
    • let和const存在块级作用域
  • 重复声明
    • var允许重复声明变量,后面声明的变量会覆盖前面的变量声明
    • let和const在同一作用域不允许重复声明变量
  • 修改声明的变量
    • var和let可以
    • const声明一个只读的常量,一旦声明,常量的值就不能改变

ES5是如何实现块级作用域的?

  • 立即执行函数实现:(函数执行完,立即被调用)
(function(name){
   console.log('hello' + name)  // hello 北京
})('北京')

let的原理

是不会在栈内存里预分配内存空间,而且在栈内存分配变量时,做一个检查,如果已经有相同变量名存在就会报错。

模板字符串

  • 基本的字符串格式化,将表达式嵌入字符串中进行拼接,用${}来定义
  • ES6反引号(``)
$('body').html(`This is ${name},${sex}`)

解构赋值

原因:有时对象中嵌套对象,取值时就会出现很长的访问链

  • 对象的结构赋值
let person = {
    name:'tom',
    sex:'male'
}
const {name,sex} = person
console.log(name)   // tom
console.log(sex)    // male

// 默认值:如果指定的局部变量名称在对象中不存在,那么这个局部变量会被赋值为undefined
console.log(age)  // undefined
  • 数组的结构赋值

  • 字符串解构

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

  • 应用场景
    • 交换变量值:[x,y]= [y,x]
    • 返回函数多个值:const [x,y,z] = Func()
    • 定义函数参数:Func([1,2])
    • 提取JSON数据:const {name,age} = dataJson

proxy

  • 定义:修改某些操作的默认行为
  • 声明:const proxy = new Proxy(target,handler)
  • 入参
    • target:拦截的目标对象
    • handler:定制拦截行为

class

  • 定义:对一类具有共同特征的事物的抽象(构造函数语法糖)

  • 原理:类本身指向构造函数,所有方法定义在prototype上,可看做构造函数的另一种写法(Class===Class.prototype.constructor)

  • 方法和关键字

    • constructor():构造函数,new命令生成实例时自动调用
    • extends:继承父类
    • super:新建父类的this
    • static:定义静态属性方法
    • get:取值函数。拦截属性的取值行为
    • set:存值函数,拦截属性的存值行为
  • 继承 ES5实质:先创造子类实例的this,再将父类的属性方法添加到this上 ES6实质:先将父类实例的属性方法加到this上(调用super()),再用子类构造函数修改this