ES5 vs ES6(ES2015+)核心区别

ES5:2009发布;ES6正式名称ES2015,后续每年迭代ES2016~ES2025,日常统称ES6。下面梳理最常用、工作高频差异

一、变量声明

ES5

只有 var

  1. 函数作用域,存在变量提升
  2. 允许重复声明
  3. 没有块级作用域(if/for循环无法隔离变量)

    var a = 1;
    var a = 2; // 合法
    for(var i=0;i<3;i++){}
    console.log(i); // 3 泄露到外层

ES6

新增 let / const

  1. 块级作用域 { } 隔离
  2. 暂时性死区TDZ,声明前不能访问
  3. 不允许同作用域重复声明
  4. const 声明常量(引用类型可修改内部属性,不能重赋值)

    let a = 1;
    const PI = 3.14;
    {
      let b = 10
    }
    console.log(b) // 报错

二、函数

1. 箭头函数 ()=>{} 【ES6新增】

ES5只有普通function

// ES5
var add = function(a,b){return a+b}
// ES6
const add = (a,b) => a + b;

箭头函数特点

  • 不绑定 this:继承外层作用域this(最常用,解决回调this指向问题)
  • 没有 arguments,可用剩余参数 ...args 替代
  • 不能作为构造函数,不能new
  • 没有 prototype

2. 函数参数增强 ES6

  • 默认参数

    // ES5
    function fn(x){x = x || 0}
    // ES6
    function fn(x = 0){}
  • 剩余参数 ...rest

    function sum(a,...rest){}
  • 参数解构

三、解构赋值(ES6新增)

快速提取数组、对象属性

// 对象解构
const user = {name:"张三",age:20}
// ES5
const name = user.name;
// ES6
const {name,age} = user;

//数组解构
const [a,b] = [10,20]

四、展开运算符 ... ES6

const arr2 = [...arr1,4,5]; //数组拷贝/合并
const obj2 = {...obj1,c:10}; //对象浅拷贝

五、字符串

  1. 模板字符串 ` (反引号) ES6

    // ES5
    var str = "name:" + name + ",age:"+age;
    // ES6
    const str = `name:${name},age:${age}`

    支持换行、插值 ${表达式}

  2. ES6新增字符串方法:includes()、startsWith()、endsWith()

六、对象字面量增强 ES6

const name = "小明"
// ES5
const obj = {name:name, say:function(){}}
// ES6 属性简写、方法简写
const obj = {
  name,
  say(){}
}
// 计算属性名
const obj = {["key"+1]:100}

七、数组新特性

  • ES6:Array.from() 类数组转数组
  • find()、findIndex()、some/every原有ES5就有
  • entries() keys() values() 迭代器

八、迭代器 & for...of(ES6新增)

  • ES5:for循环、forEach、for...in(遍历对象key,不适合数组)
  • ES6:for...of 遍历可迭代对象(数组、Set、Map、字符串)

    for(const item of arr){}
    for...in:遍历键;for...of:遍历值

九、新增数据结构 ES6

ES5仅有:Object、Array
ES6新增:

  • Set:集合,元素唯一
  • Map:键可以是任意类型(ES5对象key只能字符串/Symbol)
  • WeakSet / WeakMap 弱引用,利于GC垃圾回收
  • Symbol:唯一不可重复的值,用作私有属性标识

十、类 Class(ES6语法糖)

ES5 原型模拟面向对象

// ES5
function Person(name){this.name = name}
Person.prototype.say = function(){}

// ES6 class
class Person{
  constructor(name){
    this.name = name
  }
  say(){}
}

⚠️ class只是原型的语法糖,不是真正面向对象,不存在继承隔离;支持 extends 继承、super()

十一、模块化 Module import / export ES6

ES5没有原生模块,依靠:IIFE、RequireJS、CommonJS(Node.js)
ES6 原生ESM标准

//导出
export const a = 1;
export default fn;
//导入
import fn, {a} from './mod.js'
CommonJS:运行时加载;ESM:编译期静态导入,支持Tree-Shaking

十二、Promise 异步方案 ES6

ES5异步:回调函数 → 回调地狱
ES6 原生Promise,解决嵌套回调
后续ES2017新增 async / await(Promise语法糖)

new Promise((resolve,reject)=>{})
async function query(){
  await fetch()
}

十三、其他重要特性

  1. 赋值简写:对象解构、数组解构
  2. Promise、async/await
  3. Object.assign() 对象合并(ES6)
  4. 尾调用优化
  5. 二进制/八进制数值字面量
  6. Proxy、Reflect(ES6,实现数据劫持,Vue3底层原理)

精简对比总结表

特性ES5ES6
变量var,函数作用域let/const,块级作用域
函数function箭头函数、默认参数、rest参数
字符串字符串拼接模板字符串 `...${}`
对象基础字面量属性简写、方法简写、计算属性
循环for / forEach / for..infor...of 迭代器
异步回调函数Promise + async/await
面向对象原型手写构造函数class / extends 继承语法糖
模块无原生模块(CMD/AMD)import / export ESM
数据结构Array、ObjectSet、Map、Symbol、Weak系列
解构手动取值对象/数组解构赋值
运算符无展开语法...展开运算符

开发最需要记住的重点(面试高频)

  1. var / let / const 区别、块级作用域、暂时性死区
  2. 箭头函数this指向问题
  3. class是语法糖,底层依旧原型
  4. ESM 和 CommonJS 的差异
  5. Promise解决回调地狱,async await简化Promise
  6. 解构、模板字符串、展开运算符日常使用最多

标签: none

添加新评论