Appearance
十八、ES6 高频面试题
本节收集了 ES6 相关的高频面试题,帮助你准备面试。
let/const/var 区别
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 是 | 否(存在暂时性死区) | 否(存在暂时性死区) |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 重新赋值 | 允许 | 允许 | 不允许(引用类型可修改内部属性) |
示例
javascript
// var 的变量提升
console.log(a); // undefined
var a = 10;
// let/const 不存在变量提升
console.log(b); // 报错:Cannot access 'b' before initialization
let b = 20;
// var 允许重复声明
var c = 30;
var c = 40; // 不会报错
// let/const 不允许重复声明
let d = 50;
let d = 60; // 报错:Identifier 'd' has already been declared
// const 不能重新赋值
const e = 70;
e = 80; // 报错:Assignment to constant variable
// const 引用类型可修改内部属性
const obj = { name: 'John' };
obj.name = 'Jane'; // 不会报错箭头函数与普通函数区别
| 特性 | 普通函数 | 箭头函数 |
|---|---|---|
| this 指向 | 动态绑定,取决于调用方式 | 静态绑定,指向定义时的上下文 |
| arguments | 有 | 无 |
| 构造函数 | 可以作为构造函数 | 不能作为构造函数 |
| prototype | 有 | 无 |
| 简写形式 | 无 | 有(单参数、单语句) |
示例
javascript
// 普通函数的 this 指向
const obj1 = {
name: 'John',
sayName: function() {
console.log(this.name); // John
}
};
obj1.sayName();
// 箭头函数的 this 指向
const obj2 = {
name: 'John',
sayName: () => {
console.log(this.name); // undefined(指向全局对象)
}
};
obj2.sayName();
// 箭头函数的简写
const add1 = function(a, b) {
return a + b;
};
const add2 = (a, b) => a + b; // 简写形式Promise 原理与使用
什么是 Promise?
Promise 是一种用于处理异步操作的对象,它表示一个异步操作的最终完成(或失败)及其结果值。
Promise 的状态
- pending:初始状态,既不是成功也不是失败
- fulfilled:操作成功完成
- rejected:操作失败
Promise 的基本用法
javascript
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
promise
.then(result => {
console.log('成功:', result);
})
.catch(error => {
console.log('失败:', error);
})
.finally(() => {
console.log('无论成功失败都会执行');
});Promise.all() 与 Promise.race()
- Promise.all():接收一个 Promise 数组,当所有 Promise 都成功时返回结果数组,只要有一个失败就立即返回失败
- Promise.race():接收一个 Promise 数组,返回第一个完成的 Promise 的结果(无论成功或失败)
解构赋值、扩展运算符用法
解构赋值
javascript
// 数组解构
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
// 对象解构
const { name, age } = { name: 'John', age: 30 };
console.log(name, age); // John 30
// 函数参数解构
function printUser({ name, age }) {
console.log(`Name: ${name}, Age: ${age}`);
}
printUser({ name: 'John', age: 30 }); // Name: John, Age: 30扩展运算符
javascript
// 数组扩展
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
// 对象扩展
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 }
// 剩余参数
function sum(...args) {
return args.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10异步编程发展历程
1. 回调函数
javascript
// 回调地狱
function getData(callback) {
setTimeout(() => {
callback('数据');
}, 1000);
}
getData(data => {
console.log(data);
});2. Promise
javascript
// Promise 链式调用
function getData() {
return new Promise(resolve => {
setTimeout(() => {
resolve('数据');
}, 1000);
});
}
getData()
.then(data => {
console.log(data);
});3. async/await
javascript
// async/await
async function getData() {
return new Promise(resolve => {
setTimeout(() => {
resolve('数据');
}, 1000);
});
}
async function main() {
const data = await getData();
console.log(data);
}
main();模块化的优点
- 代码组织:将代码分割成多个文件,结构更清晰
- 作用域隔离:每个模块有自己的作用域,避免全局变量污染
- 代码复用:模块可以被多个其他模块导入使用
- 依赖管理:明确模块之间的依赖关系
- Tree Shaking:打包工具可以移除未使用的代码,减小 bundle 体积
ES6 新特性总结
- 变量声明:let、const
- 解构赋值:数组解构、对象解构
- 箭头函数:简化函数写法,改变 this 指向
- 模板字符串:支持变量插入和多行文本
- 扩展运算符:数组扩展、对象扩展、剩余参数
- 函数增强:默认参数、rest 参数
- 数组新方法:map、filter、forEach、find、some、every、reduce
- 对象增强:属性简写、方法简写、计算属性名
- Set 与 Map:新的数据结构
- Promise:异步编程方案
- async/await:异步编程终极方案
- Class:面向对象编程
- 模块化:import/export
- 字符串新方法:includes、startsWith、endsWith、repeat、padStart、padEnd
- 数值与对象新方法:Number.isFinite()、Object.keys()、Object.values()、Object.entries()
通过本章节的学习,你已经掌握了 ES6 相关的高频面试题。这些问题涵盖了 ES6 的核心特性,是面试中常见的考点。
