ES6+ 新特性

1. 变量声明 (let & const)

ES6 引入了 letconst 替代 var

  • 块级作用域 (Block Scope): 只在 {} 内有效。
  • 不存在变量提升 (Hoisting): 必须先声明再使用,否则报错(暂时性死区 Temporal Dead Zone)。
  • 不可重复声明: 同一作用域内不能多次声明同名变量。
  • const: 声明常量,必须初始化,且引用地址不可修改(对象属性可修改)。

2. 箭头函数

const add = (a, b) => a + b;

特点:

  1. 没有自己的 this: 它继承外层作用域的 this,且无法通过 call, apply, bind 改变。
  2. 没有 arguments: 使用剩余参数 ...args 代替。
  3. 不能作为构造函数: 不能使用 new
  4. 没有 prototype 属性

3. 解构赋值

从数组或对象中提取值,对变量进行赋值。

// 数组解构
const [x, y] = [1, 2];
console.log(x); // 1

// 对象解构 (常用)
const { name, age } = { name: 'Tom', age: 18 };
console.log(name); // 'Tom'

// 默认值 & 重命名
const { width: w = 100 } = props;

4. 模板字符串

使用反引号 ` 包裹,支持多行字符串和变量插值 ${expr}

const name = 'World';
const str = `Hello, ${name}!`;

5. 剩余参数 (Rest) 与 扩展运算符 (Spread)

// Rest (...)
function sum(...args) {
  return args.reduce((a, b) => a + b, 0);
}

// Spread (...)
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]
const obj = { ...obj1, c: 3 }; // 浅拷贝

6. Class 类

ES6 class 只是原型的语法糖,底层实现仍然是基于原型的。

class Person {
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    console.log(`Hello ${this.name}`);
  }
}

class Student extends Person {
  constructor(name, score) {
    super(name); // 必须在 this 之前调用
    this.score = score;
  }
}

7. 模块化

  • import: 导入模块。
  • export: 导出模块。
  • 静态加载: 在编译时确定依赖关系,支持 Tree Shaking。
// math.js
export const add = (a, b) => a + b;
export default function sub(a, b) { return a - b; }

// main.js
import sub, { add } from './math.js';

8. Promise (见 JavaScript 异步编程)

9. Proxy & Reflect

Proxy 用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。Vue 3 响应式原理使用了 Proxy。

const handler = {
  get: function(target, prop, receiver) {
    return prop in target ? target[prop] : 37;
  }
};
const p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 37

10. Symbol

一种新的原始数据类型,表示独一无二的值。常用于定义对象的私有属性或避免属性名冲突。

11. Map & Set

  • Map: 类似于对象,但键不限于字符串(可以是对象、函数等)。有序(按插入顺序)。
  • Set: 成员唯一(去重),类似于数组但不可重复。
const s = new Set([1, 2, 2, 3]);
console.log([...s]); // [1, 2, 3] (数组去重)

12. 面试常见问题

Q:var,let,const 区别?

  • var: 函数作用域,存在变量提升,可重复声明。
  • let/const: 块级作用域,存在暂时性死区,不可重复声明。

Q: 箭头函数与普通函数的区别?

(见上文第 2 点)

Q: ES Module 与 CommonJS 的区别?

  • 输出: CommonJS 输出值的拷贝(运行时加载),ESM 输出值的引用(编译时输出接口)。
  • 加载: CommonJS 运行时加载,ESM 编译时输出接口(可以做 Tree Shaking)。
  • this: CommonJS 指向 module.exports,ESM 指向 undefined