JavaScript-ES5-vs-ES6-核心特性对比
目录
JavaScript ES5 vs ES6 核心特性对比
概述
ES6(ECMAScript 2015)引入了大量现代化语法和新特性,使 JavaScript 更加简洁、易读、易维护。以下是 ES5 与 ES6 的核心特性详细对比。
核心特性对比
1. 变量声明
ES5:var
(函数作用域)
// var 声明 - 函数作用域
var x = 10;
if (true) {
var x = 20; // 同一个变量(变量提升)
console.log(x); // 20
}
console.log(x); // 20
// 函数作用域示例
function test() {
var y = 30;
}
// console.log(y); // ReferenceError: y is not defined
⚠️
var
存在变量提升和函数作用域问题,容易导致意外覆盖。
ES6:let
和 const
(块级作用域)
// let 声明 - 块级作用域
let a = 10;
if (true) {
let a = 20; // 不同的变量
console.log(a); // 20
}
console.log(a); // 10
// const 声明 - 常量(不可重新赋值)
const PI = 3.14159;
// PI = 3.14; // TypeError: Assignment to constant variable
// 块级作用域示例
{
const blockScoped = "只在块内有效";
console.log(blockScoped); // 正常输出
}
// console.log(blockScoped); // ReferenceError: blockScoped is not defined
let
和const
支持块级作用域,避免变量污染。
2. 箭头函数
ES5:传统函数与 this
问题
// 普通函数
function add(a, b) {
return a + b;
}
// 函数表达式
var multiply = function(a, b) {
return a * b;
};
// this 指向问题
var obj = {
value: 10,
getValue: function() {
var self = this; // 需手动保存 this
setTimeout(function() {
console.log(self.value); // 10
console.log(this.value); // undefined(this 指向全局)
}, 100);
}
};
ES6:箭头函数(词法绑定 this
)
// 箭头函数语法
const add = (a, b) => a + b;
const multiply = (a, b) => { return a * b; };
// 单参数可省略括号
const square = x => x * x;
// 解决 this 问题
const obj = {
value: 10,
getValue: function() {
setTimeout(() => {
console.log(this.value); // 10(继承外层 this)
}, 100);
}
};
// 注意:箭头函数不能作为构造函数
// const Person = (name) => { this.name = name; }; // TypeError
箭头函数没有自己的
this
,继承外层作用域,避免this
指向混乱。
3. 模板字符串
ES5:字符串拼接
var name = "张三";
var age = 25;
var message = "我叫" + name + ",今年" + age + "岁。";
// 多行字符串需转义
var multiLine = "第一行\n\
第二行\n\
第三行";
ES6:模板字符串(反引号 + 插值)
const name = "张三";
const age = 25;
const message = `我叫${name},今年${age}岁。`;
// 多行字符串直接书写
const multiLine = `第一行
第二行
第三行`;
// 表达式嵌入
const calculation = `2 + 3 = ${2 + 3}`;
// 标签模板(高级用法)
function tag(strings, ...values) {
console.log(strings); // ["Hello ", "!"]
console.log(values); // ["World"]
return strings[0] + values[0].toUpperCase() + strings[1];
}
const result = tag`Hello ${"world"}!`; // "Hello WORLD!"
模板字符串支持多行文本和表达式嵌入,极大提升可读性。
4. 解构赋值
ES5:手动提取属性
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
var obj = { x: 10, y: 20 };
var x = obj.x;
var y = obj.y;
// 交换变量需临时变量
var temp = a;
a = b;
b = temp;
ES6:解构赋值
// 数组解构
const [a, b, c] = [1, 2, 3];
const [first, ...rest] = [1, 2, 3, 4]; // rest = [2, 3, 4]
// 对象解构
const { x, y } = { x: 10, y: 20 };
const { name: userName, age: userAge } = { name: "李四", age: 30 };
// 默认值
const { width = 100, height = 200 } = { width: 150 };
// 函数参数解构
function draw({ x = 0, y = 0, radius = 1 }) {
console.log(`绘制圆: (${x}, ${y}), 半径: ${radius}`);
}
// 变量交换(无需临时变量)
let x = 1, y = 2;
[x, y] = [y, x]; // x=2, y=1
解构让数据提取更简洁,支持默认值和嵌套。
5. 函数参数默认值和剩余参数
ES5:手动处理默认值和参数
function multiply(a, b) {
b = b || 1; // 默认值处理(有缺陷)
return a * b;
}
function sum() {
var args = Array.prototype.slice.call(arguments);
return args.reduce(function(acc, val) {
return acc + val;
}, 0);
}
ES6:默认值与剩余参数
// 参数默认值
function multiply(a, b = 1) {
return a * b;
}
// 剩余参数(...rest)
function sum(...numbers) {
return numbers.reduce((acc, val) => acc + val, 0);
}
// 结合使用
function createPerson(name, age, ...hobbies) {
return {
name,
age,
hobbies: hobbies.length ? hobbies : ['阅读']
};
}
console.log(multiply(5)); // 5
console.log(sum(1, 2, 3, 4)); // 10
...
语法统一了参数处理,更直观可靠。
6. 类和面向对象
ES5:构造函数 + 原型链
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
return "你好,我是" + this.name;
};
// 继承
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.study = function() {
return this.name + "正在学习";
};
var student = new Student("王五", 20, "大三");
ES6:class
语法
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
return `你好,我是${this.name}`;
}
static isAdult(age) {
return age >= 18;
}
get info() {
return `${this.name} - ${this.age}岁`;
}
}
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
study() {
return `${this.name}正在学习`;
}
sayHello() {
return super.sayHello() + `,我是${this.grade}的学生`;
}
}
const student = new Student("王五", 20, "大三");
console.log(Student.isAdult(20)); // true
class
语法更接近传统 OOP,继承清晰,支持static
、get
、set
。
7. 模块化
ES5:IIFE 模拟模块
// math.js
var MathUtils = (function() {
var privateVar = 10;
function privateFunction() { return privateVar; }
return {
add: function(a, b) { return a + b; },
multiply: function(a, b) { return a * b; }
};
})();
// main.js
console.log(MathUtils.add(2, 3)); // 5
ES6:import
/ export
// math.js
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export default function multiply(a, b) { return a * b; }
// main.js
import multiply, { PI, add } from './math.js';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
// 或全部导入
import * as MathUtils from './math.js';
原生模块化支持,支持命名导出、默认导出、批量导入。
8. 新的数据结构
ES5:仅数组和对象
// 手动模拟 Set 和 Map(性能差)
function createSet() { /* ... */ }
function createMap() { /* ... */ }
ES6:Set
、Map
、Symbol
、WeakSet
、WeakMap
// Set:唯一值集合
const set = new Set([1, 2, 2, 3]);
console.log(set.size); // 3
console.log(set.has(1)); // true
// Map:键值对(支持任意类型键)
const map = new Map();
map.set('name', '张三');
console.log(map.get('name')); // '张三'
// WeakSet / WeakMap:弱引用,不阻止垃圾回收
const weakSet = new WeakSet();
const weakMap = new WeakMap();
// Symbol:唯一标识符
const sym1 = Symbol('id');
const sym2 = Symbol('id');
console.log(sym1 === sym2); // false
提供更强大的数据结构,解决 ES5 的局限性。
9. 迭代器和生成器
ES5:手动遍历
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) { console.log(arr[i]); }
// 自定义迭代器
function createRange(start, end) {
var current = start;
return {
next: function() {
return current <= end ?
{ value: current++, done: false } :
{ done: true };
}
};
}
ES6:for...of
、迭代器协议、生成器
// 迭代器协议
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
// for...of 遍历
for (const item of arr) {
console.log(item);
}
// 生成器函数
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next().value); // 1
// 可迭代对象
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
return {
next() {
return current <= this.to ?
{ value: current++, done: false } :
{ done: true };
}
};
}
};
for (let num of range) console.log(num); // 1, 2, 3
统一了遍历接口,支持自定义可迭代对象。
10. Promise 和异步编程
ES5:回调地狱
asyncTask1(function(err, result1) {
if (err) return;
asyncTask2(result1, function(err, result2) {
if (err) return;
console.log("最终结果:", result2);
});
});
ES6:Promise
function asyncTask1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("任务1完成");
resolve("结果1");
}, 1000);
});
}
// 链式调用
asyncTask1()
.then(result1 => asyncTask2(result1))
.then(finalResult => console.log("最终结果:", finalResult))
.catch(error => console.error("错误:", error));
// Promise.all 并发执行
Promise.all([asyncTask1(), asyncTask2("直接调用")])
.then(results => console.log("所有任务完成:", results));
Promise 解决回调嵌套,支持链式调用和错误统一处理。
11. 对象字面量增强
ES5:冗长写法
var name = "张三";
var person = {
name: name,
sayHello: function() { return "你好," + this.name; }
};
var obj = {};
obj[propName] = "值";
ES6:简洁语法
const name = "张三";
const person = {
name, // 属性简写
sayHello() { return `你好,${this.name}`; }, // 方法简写
[propName]: "动态属性", // 计算属性名
['computed_' + 'prop']: "计算属性"
};
// 解构赋值
const { name: userName, ...rest } = person;
语法更简洁,支持动态和计算属性。
12. 数组方法增强
ES5:基础方法
var doubled = arr.map(function(item) { return item * 2; });
var evens = arr.filter(function(item) { return item % 2 === 0; });
ES6:新方法与扩展运算符
// Array.from:类数组转数组
const divArray = Array.from(document.querySelectorAll('div'));
// Array.of:创建数组
const arr = Array.of(1, 2, 3);
// find / findIndex
const found = arr.find(x => x > 3);
const idx = arr.findIndex(x => x > 3);
// includes
arr.includes(3); // true
// 扩展运算符
const combined = [...arr1, ...arr2];
更强大的数组操作能力。
总结
对比总结
特性 | ES5 | ES6 |
---|---|---|
变量声明 | var (函数作用域) | let /const (块级作用域) |
函数 | function 声明 | 箭头函数、默认参数、剩余参数 |
字符串 | 拼接、转义 | 模板字符串、插值、多行 |
对象 | 完整写法 | 属性简写、方法简写、计算属性 |
数组 | map /filter /reduce | find 、includes 、Array.from 、扩展运算符 |
异步 | 回调函数 | Promise 、async/await (后续) |
模块化 | IIFE、CommonJS | import /export 原生支持 |
类 | 构造函数 + 原型 | class 语法、继承、super |
数据结构 | 数组、对象 | Set 、Map 、Symbol 、WeakMap |
迭代 | for 循环、forEach | for...of 、迭代器、生成器 |
推荐
ES6 极大地提升了 JavaScript 的开发体验:
- 语法更简洁、可读性更强
- 解决了
this
、作用域、回调地狱等历史问题 - 引入现代编程范式(函数式、面向对象、模块化)
- 提供强大新特性(Promise、类、解构、模板字符串等)
💡 推荐在现代项目中优先使用 ES6+ 语法,结合 Babel 等工具兼容旧环境。