Skip to content

ES6高频面试题(30题)

1. 什么是ES6?它的主要特性有哪些?

参考答案:

ES6(ECMAScript 2015)是JavaScript的第六个版本,是JavaScript语言的重大更新。主要特性包括:

  • let和const关键字

  • 箭头函数

  • 模板字符串

  • 解构赋值

  • 默认参数

  • 扩展运算符

  • Promise

  • 类(Class)

  • 模块化(import/export)

  • Symbol数据类型

  • Map和Set数据结构

  • 生成器函数(Generator)

2. let、const和var的区别是什么?

参考答案:

  • 作用域:var是函数作用域,let和const是块级作用域

  • 变量提升:var存在变量提升,let和const存在暂时性死区

  • 重复声明:var允许重复声明,let和const不允许

  • 赋值:var和let可以重新赋值,const不能重新赋值(但对象内容可修改)

  • 初始化:var和let可以不初始化,const必须初始化

3. 什么是箭头函数?它与普通函数有什么区别?

参考答案:

箭头函数是ES6新增的函数定义方式,语法更简洁。主要区别:

  • this指向:箭头函数没有自己的this,继承外层作用域的this

  • arguments对象:箭头函数没有arguments对象

  • 构造函数:箭头函数不能作为构造函数使用

  • 原型:箭头函数没有prototype属性

  • 变量提升:箭头函数不存在变量提升

4. 什么是模板字符串?它有什么优势?

参考答案:

模板字符串使用反引号(`)包围,可以包含占位符(${expression})。优势:

  • 支持多行字符串

  • 支持变量插值

  • 支持表达式计算

  • 更直观的字符串拼接

  • 支持标签模板功能

5. 解构赋值是什么?请举例说明数组和对象的解构。

参考答案:

解构赋值是一种从数组或对象中提取值并赋给变量的语法。

JavaScript
// 数组解构
const [a, b, c] = [1, 2, 3];
const [x, , z] = [1, 2, 3]; // 跳过中间元素

// 对象解构
const {name, age} = {name: 'John', age: 30};
const {name: userName, age: userAge} = obj; // 重命名

6. 什么是扩展运算符(...)?它有哪些用途?

参考答案:

扩展运算符(...)可以将可迭代对象展开。用途包括:

  • 数组展开:[...arr1, ...arr2]

  • 对象展开:{...obj1, ...obj2}

  • 函数参数展开:func(...args)

  • 复制数组/对象:[...arr]{...obj}

  • 将类数组对象转为数组:[...nodeList]

7. 什么是剩余参数(rest parameters)?

参考答案:

剩余参数使用...语法,将多个参数收集到一个数组中:

JavaScript
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // numbers = [1, 2, 3, 4]

剩余参数必须是最后一个参数,一个函数只能有一个剩余参数。

8. ES6中的默认参数是如何工作的?

参考答案:

ES6允许为函数参数设置默认值:

JavaScript
function greet(name = 'World') {
  return `Hello, ${name}!`;
}
  • 只有当参数为undefined时才使用默认值

  • 默认参数可以是表达式或函数调用

  • 默认参数可以引用前面的参数

  • 有默认值的参数应该放在后面

9. 什么是Promise?它解决了什么问题?

参考答案:

Promise是处理异步操作的对象,有三种状态:pending、fulfilled、rejected。

解决的问题:

  • 回调地狱问题

  • 错误处理困难

  • 异步操作的组合和串联

  • 提供了更好的异步编程模式

基本用法:

JavaScript
const promise = new Promise((resolve, reject) => {
  // 异步操作
});
promise.then(result => {}).catch(error => {});

10. ES6的类(Class)是如何工作的?

参考答案:

ES6的类是基于原型的语法糖:

JavaScript
class Person {
  constructor(name) {
    this.name = name;
  }
  
  sayHello() {
    return `Hello, I'm ${this.name}`;
  }
  
  static getSpecies() {
    return 'Homo sapiens';
  }
}
  • constructor定义构造函数

  • 方法定义在原型上

  • 支持静态方法

  • 支持继承(extends)

11. ES6模块化(import/export)是如何工作的?

参考答案:

ES6提供了原生的模块化支持:

JavaScript
// 导出
export const name = 'John';
export function greet() {}
export default class Person {}

// 导入
import Person, { name, greet } from './module.js';
import * as utils from './utils.js';
  • 静态导入导出

  • 编译时确定依赖关系

  • 支持默认导出和命名导出

  • 自动严格模式

12. Symbol数据类型有什么特点和用途?

参考答案:

Symbol是ES6新增的原始数据类型,表示独一无二的值。特点:

  • 每个Symbol值都是唯一的

  • 不能与其他值进行运算

  • 可以作为对象属性名

  • 不会被常规方法遍历到

用途:

  • 创建对象的私有属性

  • 定义对象的元数据

  • 避免属性名冲突

  • 实现迭代器接口

13. Map和Set数据结构有什么特点?

参考答案:

Map特点:

  • 键值对集合,键可以是任意类型

  • 有序,按插入顺序遍历

  • size属性获取大小

  • 方法:set、get、has、delete、clear

Set特点:

  • 值的集合,值唯一

  • 有序,按插入顺序遍历

  • size属性获取大小

  • 方法:add、has、delete、clear

  • 可用于数组去重

14. 什么是生成器函数(Generator)?

参考答案:

生成器函数是可以暂停和恢复执行的函数,使用function*定义:

JavaScript
function* generator() {
  yield 1;
  yield 2;
  return 3;
}

const gen = generator();
gen.next(); // {value: 1, done: false}
gen.next(); // {value: 2, done: false}
gen.next(); // {value: 3, done: true}

特点:

  • 返回迭代器对象

  • 可以暂停和恢复执行

  • 用于实现异步编程

  • 可以双向通信

15. 什么是迭代器(Iterator)和可迭代对象?

参考答案:

迭代器:实现了next()方法的对象,返回{value, done}格式的结果。

可迭代对象:实现了Symbol.iterator方法的对象。

内置可迭代对象:Array、String、Map、Set、arguments等。

JavaScript
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
iterator.next(); // {value: 1, done: false}

16. for...of和for...in的区别是什么?

参考答案:

  • for...in:遍历对象的可枚举属性名(包括继承的)

  • for...of:遍历可迭代对象的值

JavaScript
const arr = [1, 2, 3];
arr.name = 'array';

for (let key in arr) {
  console.log(key); // 0, 1, 2, name
}

for (let value of arr) {
  console.log(value); // 1, 2, 3
}

17. 什么是Proxy?它有什么用途?

参考答案:

Proxy用于定义基本操作的自定义行为(如属性查找、赋值等):

JavaScript
const proxy = new Proxy(target, handler);

用途:

  • 属性访问拦截

  • 函数调用拦截

  • 数据验证

  • 属性默认值

  • 实现观察者模式

  • Vue3的响应式原理

常用handler方法:get、set、has、deleteProperty等。

18. 什么是Reflect?它与Proxy有什么关系?

参考答案:

Reflect是一个内置对象,提供了拦截JavaScript操作的方法。

特点:

  • 方法与Proxy handler方法一一对应

  • 提供了默认的对象操作行为

  • 返回值更合理(布尔值而不是抛出异常)

JavaScript
// 传统方式
delete obj.prop;

// Reflect方式
Reflect.deleteProperty(obj, 'prop'); // 返回boolean

与Proxy配合使用可以实现更好的元编程。

19. 什么是WeakMap和WeakSet?它们与Map、Set有什么区别?

参考答案:

WeakMap和WeakSet的特点:

  • 键/值必须是对象

  • 弱引用,不阻止垃圾回收

  • 不可遍历,没有size属性

  • 没有clear方法

与Map、Set的区别:

  • 引用类型:弱引用 vs 强引用

  • 垃圾回收:不阻止 vs 阻止

  • 遍历性:不可遍历 vs 可遍历

  • 用途:存储私有数据 vs 一般数据存储

20. 什么是暂时性死区(Temporal Dead Zone)?

参考答案:

暂时性死区是指let和const声明的变量在声明之前不能被访问的区域。

JavaScript
console.log(a); // ReferenceError
let a = 1;

function func() {
  console.log(b); // ReferenceError
  let b = 2;
}

特点:

  • 从块级作用域开始到变量声明之前

  • 访问会抛出ReferenceError

  • typeof操作符也会报错

  • 确保变量先声明后使用

21. ES6中的对象字面量有哪些增强?

参考答案:

ES6对象字面量增强包括:

  1. 属性简写{name, age} 等价于 {name: name, age: age}

  2. 方法简写{method() {}} 等价于 {method: function() {}}

  3. 计算属性名{[key]: value}

  4. 可以使用表达式作为属性名

  5. super关键字:在方法中调用原型方法

JavaScript
const name = 'John';
const obj = {
  name,                    // 属性简写
  greet() {},             // 方法简写
  [name + 'Key']: 'value' // 计算属性名
};

22. 什么是数组的新方法?请列举几个ES6新增的数组方法。

参考答案:

ES6为数组新增了多个方法:

  • Array.from():将类数组对象转为数组

  • Array.of():创建数组,避免Array构造函数的怪异行为

  • find():找到第一个满足条件的元素

  • findIndex():找到第一个满足条件的元素索引

  • includes():判断数组是否包含某个值

  • fill():用指定值填充数组

  • keys()、values()、entries():返回迭代器

23. 什么是字符串的新方法?ES6为字符串添加了哪些方法?

参考答案:

ES6为字符串新增的方法:

  • includes():判断是否包含子字符串

  • startsWith():判断是否以指定字符串开头

  • endsWith():判断是否以指定字符串结尾

  • repeat():重复字符串指定次数

  • padStart():在开头填充字符串到指定长度

  • padEnd():在末尾填充字符串到指定长度

JavaScript
'hello'.includes('ell'); // true
'hello'.startsWith('he'); // true
'hello'.repeat(2); // 'hellohello'

24. 什么是参数解构?请举例说明。

参考答案:

参数解构是在函数参数中直接解构传入的对象或数组:

JavaScript
// 对象参数解构
function greet({name, age = 18}) {
  console.log(`Hello ${name}, age ${age}`);
}
greet({name: 'John', age: 25});

// 数组参数解构
function sum([a, b]) {
  return a + b;
}
sum([1, 2]);

// 嵌套解构
function process({user: {name, email}}) {
  console.log(name, email);
}

25. 什么是尾调用优化?ES6如何支持尾调用优化?

参考答案:

尾调用是指函数的最后一步调用另一个函数。尾调用优化是指在尾调用时不增加新的栈帧,而是复用当前栈帧。

ES6在严格模式下支持尾调用优化:

JavaScript
'use strict';
function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return factorial(n - 1, n * acc); // 尾调用
}

条件:

  • 严格模式

  • 尾调用不访问当前栈帧的变量

  • 尾调用是函数的最后一个操作

26. 什么是标签模板?它有什么用途?

参考答案:

标签模板是模板字符串的高级形式,允许用函数解析模板字符串:

JavaScript
function highlight(strings, ...values) {
  return strings.reduce((result, string, i) => {
    return result + string + (values[i] ? `<mark>${values[i]}</mark>` : '');
  }, '');
}

const name = 'John';
const age = 25;
const result = highlight`Hello ${name}, you are ${age} years old`;

用途:

  • 字符串处理和转换

  • 模板引擎

  • 国际化

  • 防止XSS攻击

27. ES6中的正则表达式有哪些新特性?

参考答案:

ES6为正则表达式添加了新特性:

  1. u标志:Unicode模式,正确处理大于\uFFFF的Unicode字符

  2. y标志:粘连模式,从lastIndex位置开始匹配

  3. RegExp构造函数增强:可以接受正则表达式作为参数

  4. 新方法:flags属性获取修饰符

JavaScript
const regex = /\u{1D306}/u; // Unicode模式
const sticky = /hello/y;    // 粘连模式
regex.flags; // 'u'

28. 什么是二进制和八进制字面量?

参考答案:

ES6提供了二进制和八进制数值的新写法:

JavaScript
// 二进制(0b或0B开头)
const binary = 0b1010; // 10
const binary2 = 0B1010; // 10

// 八进制(0o或0O开头)
const octal = 0o755; // 493
const octal2 = 0O755; // 493

// 检测方法
Number.isFinite(binary); // true
Number.isInteger(octal); // true

注意:严格模式下不支持0开头的八进制写法。

29. ES6中的Number对象有哪些新方法?

参考答案:

ES6为Number对象新增了多个方法:

  • Number.isFinite():检测数值是否有限

  • Number.isNaN():检测是否为NaN

  • Number.parseInt():解析整数

  • Number.parseFloat():解析浮点数

  • Number.isInteger():判断是否为整数

  • Number.isSafeInteger():判断是否在安全整数范围内

  • Number.EPSILON:最小精度常量

  • Number.MAX_SAFE_INTEGER/MIN_SAFE_INTEGER:安全整数范围

30. 什么是Object.assign()?它有什么特点和用途?

参考答案:

Object.assign()用于将源对象的可枚举属性复制到目标对象:

JavaScript
const target = {a: 1};
const source = {b: 2, c: 3};
Object.assign(target, source); // {a: 1, b: 2, c: 3}

特点:

  • 浅拷贝,不会拷贝继承属性和不可枚举属性

  • 同名属性会被覆盖

  • 返回目标对象

  • 可以接受多个源对象

用途:

  • 对象合并

  • 对象克隆

  • 为对象添加属性

  • 为对象添加方法

最近更新