ES6+ 核心语法速通

为什么要先学 ES6+

ES6 (ES2015) 是 JavaScript 的现代化起点。在那之前的 JS 写起来像玩具语言,之后才真正具备了写大型应用的能力。Vue 3 的源码、TypeScript、以及几乎所有现代前端库,都大量使用 ES6+ 语法。

Java 类比:ES6 之于 JS,大概相当于 Java 8 的 Lambda + Stream + Optional 那一波更新——都是让语言从"能用"变成"好用"的分水岭。


1. 变量声明:let / const 取代 var

// 旧写法(少碰)
var name = 'foo'

// 新写法
let age = 18        // 可变
const MAX = 100     // 不可变(但对象里的属性还是能改)

Java 对照

Java JS
int age = 18; let age = 18
final int MAX = 100; const MAX = 100

坑点


2. 箭头函数:轻量级 Lambda

// 普通函数
function add(a, b) {
  return a + b
}

// 箭头函数
const add = (a, b) => a + b

Java 对照

// Java 8 Lambda
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;

关键差异:Java 的 Lambda 里 this 指向外部类;JS 的箭头函数里 this 也指向外层作用域。但普通 function 里的 this 是个坑——谁调用它就是谁,和 Java 完全不一样。

const obj = {
  count: 0,
  // ❌ 这里不要用箭头函数,this 会指向全局而非 obj
  bad: () => { this.count++ },
  // ✅ 方法简写,this 正确指向 obj
  good() { this.count++ },
}

建议:回调函数用箭头函数,对象方法用简写。


3. 解构赋值:一次取多个值

const user = { name: 'foo', age: 18, email: 'f@x.com' }

// 对象解构
const { name, age } = user
// 等价于 const name = user.name; const age = user.age;

// 数组解构
const [first, second] = [10, 20]

// 重命名 + 默认值
const { name: userName, role = 'guest' } = user

Java 对照:Java 没有解构。在 Java 里你得写:

String name = user.getName();
int age = user.getAge();

常见用途:函数参数直接解构,等价于 Java 的命名参数。

function createUser({ name, age, role = 'user' }) {
  // ...
}
createUser({ name: 'foo', age: 18 })

4. 模板字符串:告别字符串拼接

const name = 'foo'
const greeting = `Hello, ${name}! Today is ${new Date().toLocaleDateString()}.`

// 多行字符串也很自然
const html = `
  <div>
    <h1>${title}</h1>
  </div>
`

Java 对照:类似 Java 15 的文本块 """...""",加上 String.format() 或 Java 21 的 STR."Hello \{name}" 模板。


5. 扩展运算符 (...)

// 数组
const arr1 = [1, 2, 3]
const arr2 = [0, ...arr1, 4]   // [0, 1, 2, 3, 4]

// 对象合并
const base = { a: 1, b: 2 }
const extended = { ...base, c: 3 }   // { a: 1, b: 2, c: 3 }

// 函数参数收集
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0)
}
sum(1, 2, 3, 4)   // 10

Java 对照

注意:对象扩展是浅拷贝。嵌套对象还是引用。


6. Promise 与 async/await:告别回调地狱

这是 ES6+ 最重要的更新之一。前端几乎所有异步操作(网络请求、定时器、文件读写)都用它。

// 用 Promise
fetch('/api/user')
  .then(res => res.json())
  .then(user => console.log(user))
  .catch(err => console.error(err))

// 用 async/await(推荐)
async function loadUser() {
  try {
    const res = await fetch('/api/user')
    const user = await res.json()
    console.log(user)
  } catch (err) {
    console.error(err)
  }
}

Java 对照

Java JS
CompletableFuture<T> Promise<T>
.thenApply(fn) .then(fn)
.exceptionally(fn) .catch(fn)
Java 19+ 虚拟线程让异步代码看起来同步 async/await

关键理解

常见坑:忘记 await 导致拿到的是 Promise 对象而不是结果值。


7. 模块化:import / export

// user.js
export function getUser() { /* ... */ }
export const USER_ROLE = 'admin'
export default class UserService { /* ... */ }

// main.js
import UserService, { getUser, USER_ROLE } from './user.js'

Java 对照

import * as UserModule from './user.js'   // 全部导入成命名空间
import { getUser as fetchUser } from './user.js'  // 重命名

8. 可选链 (?.) 与空值合并 (??)

这是 ES2020 加进来的,写 JS 和 TS 时非常常用。

// 可选链:避免 TypeError
const city = user?.address?.city   // 任何一层是 null/undefined 就返回 undefined

// 空值合并:只在 null/undefined 时用默认值
const name = user.name ?? '匿名'
// 注意:|| 会把 '' 和 0 也当"假值"处理,?? 只看 null/undefined

Java 对照


9. 数组高阶方法:函数式风格

const nums = [1, 2, 3, 4, 5]

nums.map(n => n * 2)           // [2, 4, 6, 8, 10]
nums.filter(n => n % 2 === 0)  // [2, 4]
nums.reduce((sum, n) => sum + n, 0)  // 15
nums.find(n => n > 3)          // 4
nums.some(n => n > 4)          // true
nums.every(n => n > 0)         // true

Java 对照:几乎一一对应 Java 8 Stream API。

nums.stream().map(n -> n * 2).toList();
nums.stream().filter(n -> n % 2 == 0).toList();
nums.stream().reduce(0, (a, b) -> a + b);

差异


小结:速查表

特性 一句话
let / const 取代 var,块级作用域
箭头函数 => 短函数 + 绑定外层 this
解构 { a, b } = obj 批量取值
模板字符串 ` ` 拼接字符串 + 多行
扩展运算符 ... 展开数组/对象、收集参数
async / await 写起来像同步的异步
import / export 模块化
?. / ?? 空值安全
数组高阶方法 函数式风格,类似 Stream

延伸阅读


下一篇:TypeScript 基础(从 Java 视角看 TS 的类型系统)