《前端面试题:ES6新特性》
JavaScript ES6新特性深度解析:现代前端开发的基石
ES6(ECMAScript 2015)是JavaScript发展史上里程碑式的更新,它引入了大量革命性特性,彻底改变了JavaScript的编程范式。本文将全面剖析ES6的核心特性,涵盖语法增强、新数据类型、异步编程等关键内容,并提供大量代码示例和面试题解析。
一、ES6概述:为什么它如此重要?
ES6是JavaScript语言的第六个版本,发布于2015年。它解决了ES5的许多痛点,提供了更简洁、更强大的语法和功能:
- 代码更简洁:箭头函数、解构赋值等特性减少样板代码
- 功能更强大:Promise、类、模块等支持复杂应用开发
- 更安全:let/const提供块级作用域,减少变量污染
- 更现代:为现代框架(React、Vue、Angular)奠定基础
二、核心特性详解
1. 变量声明:let与const
特性:
let
:块级作用域变量,可重新赋值const
:块级作用域常量,不可重新赋值(但可修改对象属性)
示例:
// let 示例
for (let i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // 0, 1, 2
}// const 示例
const PI = 3.14159;
// PI = 3; // 报错:Assignment to constant variableconst person = { name: 'Alice' };
person.name = 'Bob'; // 允许修改属性
面试题:
console.log(a); // undefined
var a = 10;console.log(b); // 报错:Cannot access 'b' before initialization
let b = 20;
解析: var存在变量提升,let存在暂时性死区
2. 箭头函数
特性:
- 更简洁的函数语法
- 没有自己的
this
(继承外层作用域) - 不能作为构造函数
示例:
// 传统函数
const sum = function(a, b) { return a + b;
};// 箭头函数
const sum = (a, b) => a + b;// this绑定示例
const obj = {name: 'ES6',print: () => console.log(this.name), // this指向windowprintTraditional: function() {console.log(this.name); // this指向obj}
};
面试题:
const obj = {value: 42,getValue: function() {return () => this.value;}
};const fn = obj.getValue();
console.log(fn()); // 42
解析: 箭头函数继承外层函数的this
3. 解构赋值
特性:
- 从数组/对象中提取值赋给变量
- 支持嵌套解构
- 默认值设置
示例:
// 数组解构
const [first, second] = [10, 20];// 对象解构
const { name, age } = { name: 'Alice', age: 30 };// 函数参数解构
function greet({ name, age = 18 }) {console.log(`Hello, ${name} (${age})`);
}// 嵌套解构
const { address: { city }
} = { name: 'Bob', address: { city: 'New York' }
};
4. 模板字符串
特性:
- 使用反引号(``)定义
- 支持多行字符串
- 支持表达式嵌入(${expression})
示例:
const name = 'Alice';
const age = 28;// 基本用法
console.log(`Hello, ${name}!`); // 多行字符串
const html = `<div><h1>${name}</h1><p>Age: ${age}</p></div>
`;// 表达式计算
console.log(`Next year you will be ${age + 1}`);
5. 函数参数增强
特性:
- 默认参数值
- Rest参数(收集剩余参数)
- 扩展运算符(展开数组/对象)
示例:
// 默认参数
function greet(name = 'Guest') {console.log(`Hello, ${name}!`);
}// Rest参数
function sum(...numbers) {return numbers.reduce((acc, val) => acc + val, 0);
}// 扩展运算符
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combined = { ...obj1, ...obj2 }; // {a:1, b:2}
6. 类(Class)
特性:
- 面向对象编程的语法糖
- 构造函数、方法、继承
- 静态方法和属性
示例:
class Person {constructor(name, age) {this.name = name;this.age = age;}// 实例方法greet() {console.log(`Hello, I'm ${this.name}`);}// 静态方法static info() {console.log('This is a Person class');}
}class Student extends Person {constructor(name, age, major) {super(name, age);this.major = major;}study() {console.log(`${this.name} is studying ${this.major}`);}
}// 使用
const alice = new Student('Alice', 22, 'Computer Science');
alice.greet(); // Hello, I'm Alice
alice.study(); // Alice is studying Computer Science
Person.info(); // This is a Person class
面试题:
class A {constructor() {this.name = 'A';}print() {console.log(this.name);}
}class B extends A {constructor() {super();this.name = 'B';}print() {setTimeout(() => {super.print();}, 100);}
}const b = new B();
b.print(); // 输出什么?
答案: “B”
解析: 箭头函数继承外层this,super.print()调用A的print方法,但this指向B的实例
7. Promise与异步编程
特性:
- 解决回调地狱问题
- 三种状态:pending, fulfilled, rejected
- 链式调用(.then().catch())
示例:
function fetchData(url) {return new Promise((resolve, reject) => {setTimeout(() => {if (url.startsWith('https')) {resolve({ data: 'Success!' });} else {reject(new Error('Invalid URL'));}}, 1000);});
}// 使用
fetchData('https://api.example.com').then(response => {console.log(response.data);return processData(response);}).then(processed => {console.log('Processed:', processed);}).catch(error => {console.error('Error:', error.message);});
面试题:
console.log('Start');Promise.resolve().then(() => console.log('Promise 1')).then(() => console.log('Promise 2'));setTimeout(() => console.log('Timeout'), 0);console.log('End');
输出顺序:
Start → End → Promise 1 → Promise 2 → Timeout
解析: 微任务(Promise)优先于宏任务(setTimeout)
8. 模块系统
特性:
- 导出(export)
- 导入(import)
- 支持命名导出和默认导出
示例:
// math.js - 命名导出
export const PI = 3.14159;
export function square(x) { return x * x; }// app.js - 导入
import { PI, square } from './math.js';
console.log(square(PI));// utils.js - 默认导出
export default function() {console.log('Default export');
}// main.js - 导入默认导出
import customName from './utils.js';
customName();
9. 迭代器与生成器
特性:
- 迭代器(Iterator):实现遍历协议的对象
- 生成器(Generator):返回迭代器的特殊函数
示例:
// 自定义迭代器
const range = {from: 1,to: 5,[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,4,5
}// 生成器函数
function* generateSequence(start, end) {for (let i = start; i <= end; i++) {yield i;}
}const sequence = generateSequence(1, 3);
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
10. 新数据结构:Set与Map
Set特性:
- 值唯一的集合
- 常用方法:add, delete, has, size
Map特性:
- 键值对集合(键可以是任意类型)
- 常用方法:set, get, has, delete, size
示例:
// Set
const unique = new Set([1, 2, 2, 3, 4]);
console.log(unique); // Set(4) {1, 2, 3, 4}
console.log(unique.has(2)); // true// Map
const userMap = new Map();
userMap.set(1, { name: 'Alice' });
userMap.set('id-123', { name: 'Bob' });console.log(userMap.get(1)); // {name: 'Alice'}
console.log(userMap.size); // 2
三、ES6面试题精选
1. 闭包与块级作用域
function createFunctions() {let result = [];for (let i = 0; i < 3; i++) {result.push(() => i);}return result;
}const funcs = createFunctions();
console.log(funcs[0]()); // ?
console.log(funcs[1]()); // ?
console.log(funcs[2]()); // ?
答案: 0, 1, 2
解析: let创建块级作用域,每个i独立
2. Promise链式调用
Promise.resolve(1).then(x => x + 1).then(x => { throw new Error('Error!') }).catch(err => 3).then(x => x + 1).then(console.log);
答案: 4
解析: catch处理后继续执行后续then
3. 类继承
class Animal {constructor(name) {this.name = name;}speak() {console.log(`${this.name} makes a noise.`);}
}class Dog extends Animal {speak() {super.speak();console.log(`${this.name} barks.`);}
}const dog = new Dog('Rex');
dog.speak();
输出:
“Rex makes a noise.”
“Rex barks.”
四、ES6最佳实践
- 优先使用const:除非需要重新赋值,否则使用const
- 使用箭头函数:简化代码,避免this问题
- 模板字符串代替拼接:提高可读性
- Promise处理异步:避免回调地狱
- 类组织代码:提高代码可维护性
- 模块化开发:提高代码复用性
五、总结
ES6从根本上改变了JavaScript的编程范式:
- 变量声明:使用let/const代替var
- 函数:箭头函数、默认参数、rest参数
- 数据结构:解构赋值、Set/Map
- 异步处理:Promise优雅处理异步
- 面向对象:类与继承
- 模块化:import/export组织代码
掌握ES6不仅是现代前端开发的基本要求,也是理解React、Vue等框架的基础。本文涵盖的特性只是ES6的核心部分,实际开发中还有更多强大功能值得探索。建议在项目中积极应用这些特性,编写更简洁、更健壮的JavaScript代码。