JavaScript ES5 vs ES6 核心特性对比

简介: ES6(ECMAScript 2015)引入了`let/const`、箭头函数、模板字符串、解构赋值、类、模块化、Promise等新特性,解决了ES5中作用域、this指向、回调地狱等问题,使JavaScript语法更简洁、可读性更强,支持现代编程范式,极大提升了开发效率,推荐结合Babel在项目中使用。

@TOC

概述

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:letconst(块级作用域)

// 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

letconst 支持块级作用域,避免变量污染。


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,继承清晰,支持 staticgetset


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:SetMapSymbolWeakSetWeakMap

// 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 findincludesArray.from、扩展运算符
异步 回调函数 Promiseasync/await(后续)
模块化 IIFE、CommonJS import/export 原生支持
构造函数 + 原型 class 语法、继承、super
数据结构 数组、对象 SetMapSymbolWeakMap
迭代 for 循环、forEach for...of、迭代器、生成器

推荐

ES6 极大地提升了 JavaScript 的开发体验:

  • 语法更简洁、可读性更强
  • 解决了 this、作用域、回调地狱等历史问题
  • 引入现代编程范式(函数式、面向对象、模块化)
  • 提供强大新特性(Promise、类、解构、模板字符串等)

💡 推荐在现代项目中优先使用 ES6+ 语法,结合 Babel 等工具兼容旧环境。

相关文章
|
21天前
|
自然语言处理 JavaScript 前端开发
全面解析 i18n:从概念到实践,再到底层原理
本文系统讲解国际化(i18n)的核心概念与实现原理,涵盖多语言文本、日期、数字、复数等处理方式,结合 i18next 与 Vue I18n 实战案例,深入剖析资源分离、环境识别与动态替换三大机制,并分享插值、格式化、CI/CD 集成等最佳实践,助力构建可扩展的全球化应用。
255 15
|
1月前
|
XML Android开发 数据格式
Android setContentView源码与原理分析
`setContentView` 是 Activity 显示界面的核心方法,其本质是将布局嵌入由 `PhoneWindow` 管理的 `DecorView` 中。系统首先创建包含状态栏、标题栏等的窗口模板(如 `screen_simple.xml`),再通过 `LayoutInflater` 将开发者指定的布局加载到 ID 为 `android.R.id.content` 的 `mContentParent` 容器内,最终在 `Activity` 恢复时由 `WindowManager` 将 `DecorView` 添加至窗口,触发测量与绘制流程,完成界面显示。
191 73
|
1月前
|
SQL 运维 关系型数据库
云数据库 Clouder 认证:SQL 基础开发与应用题型分析
阿里云Clouder认证(数据库方向)考察SQL基础开发与应用能力,涵盖DDL/DML操作、多表查询、聚合统计、子查询等高频题型。考试以MySQL实操为主,注重语法准确性与逻辑严谨性,适合开发者、运维及数据工程师备考。
322 162
|
13天前
|
人工智能 运维 安全
SOC 2.0 来了:不是加人加班,而是加“智能”!——智能化安全运营中心的建设之道
SOC 2.0 来了:不是加人加班,而是加“智能”!——智能化安全运营中心的建设之道
130 15
|
14天前
|
JSON 数据挖掘 API
小红书笔记详情API接口指南
小红书笔记详情API可获取指定笔记的完整信息,涵盖内容、作者及互动数据,适用于内容分析与数据挖掘。接口采用GET请求,支持Bearer Token认证,返回JSON格式数据。代码具备完善封装、类型注解、异常处理与重试机制,需官方授权后使用,并遵守平台规范。(238字)
|
26天前
|
人工智能 算法 小程序
AI试衣技术:为什么能生成好看的图片,却难以真正用于商业场景?
本文解析AI试衣技术背后的真实挑战,指出娱乐化“AI换衣”与商业级虚拟试衣的本质差异,揭示体型适配、服装结构还原等核心难题,并探讨行业领先者如何通过多维度技术积累实现可商用的精准、真实、稳定的虚拟试穿方案。
214 5
|
14天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1529 8
|
1月前
|
缓存 JavaScript 安全
Vue 3 Props 响应式深度解析:从原理到最佳实践
本文深入解析 Vue 3 中 `props` 的响应式机制,涵盖单向数据流原理、类型安全声明、性能优化策略及高级应用场景。通过实例讲解解构响应性丢失、深层监听开销、不可变数据处理等常见问题,总结最佳实践与调试技巧,助你构建高效、可维护的组件通信体系。
212 6
|
1月前
|
人工智能 安全 Java
Spring AI 核心架构解析:构建企业级 AI 应用的 Java 新范式
Spring AI 为 Java 开发者提供企业级 AI 应用新范式,通过分层架构、统一抽象(如 ChatClient、PromptTemplate)与 Spring 生态深度集成,支持 RAG、函数调用、流式响应等核心功能,实现安全、可观测、可维护的智能系统构建。
502 8