《前端面试题:ES6新特性》

发布于:2025-06-11 ⋅ 阅读:(27) ⋅ 点赞:(0)

JavaScript ES6新特性深度解析:现代前端开发的基石

ES6(ECMAScript 2015)是JavaScript发展史上里程碑式的更新,它引入了大量革命性特性,彻底改变了JavaScript的编程范式。本文将全面剖析ES6的核心特性,涵盖语法增强、新数据类型、异步编程等关键内容,并提供大量代码示例和面试题解析。

一、ES6概述:为什么它如此重要?

ES6是JavaScript语言的第六个版本,发布于2015年。它解决了ES5的许多痛点,提供了更简洁、更强大的语法和功能:

  1. 代码更简洁:箭头函数、解构赋值等特性减少样板代码
  2. 功能更强大:Promise、类、模块等支持复杂应用开发
  3. 更安全:let/const提供块级作用域,减少变量污染
  4. 更现代:为现代框架(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 variable

const 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指向window
  printTraditional: 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最佳实践

  1. 优先使用const:除非需要重新赋值,否则使用const
  2. 使用箭头函数:简化代码,避免this问题
  3. 模板字符串代替拼接:提高可读性
  4. Promise处理异步:避免回调地狱
  5. 类组织代码:提高代码可维护性
  6. 模块化开发:提高代码复用性

五、总结

ES6从根本上改变了JavaScript的编程范式:

  • 变量声明:使用let/const代替var
  • 函数:箭头函数、默认参数、rest参数
  • 数据结构:解构赋值、Set/Map
  • 异步处理:Promise优雅处理异步
  • 面向对象:类与继承
  • 模块化:import/export组织代码

掌握ES6不仅是现代前端开发的基本要求,也是理解React、Vue等框架的基础。本文涵盖的特性只是ES6的核心部分,实际开发中还有更多强大功能值得探索。建议在项目中积极应用这些特性,编写更简洁、更健壮的JavaScript代码。