前端八股文es6篇 - 详解

好的,这里是专门针对 ES6+ 的前端面试“八股文”,它已经成为现代前端开发的绝对主流和面试必考内容。


一、核心语法与声明

1. letconst

(这部分在JS篇已详述,但它是ES6的基石,必须掌握)

  • let:块级作用域变量,不可重复声明,存在暂时性死区。
  • const:用于声明常量,必须在声明时初始化。对于基本类型,值不可改变;对于引用类型,其指向的内存地址不可改变(但属性或元素可修改)。
2. 模板字符串
  • 用法:使用反引号(`)标识。
  • 特性
    1. 字符串插值:使用 ${expression} 嵌入变量或表达式。
    const name = 'Alice';
    console.log(`Hello, ${name}!`); // Hello, Alice!
    console.log(`1 + 2 = ${1 + 2}`); // 1 + 2 = 3
    1. 多行字符串:直接换行即可,无需使用 \n 或字符串连接符。
    const multiLine = `
    This is
    a multi-line
    string.
    `;
3. 箭头函数
  • 语法(parameters) => { statements }parameter => expression(单一参数可省略括号,单一表达式可省略大括号并隐式返回)。
  • 特性与限制
    1. 没有自己的 this:它继承自定义它时所处的外层作用域的 this。这使得它特别适合用在回调函数(如 setTimeout, map, filter)中,避免 this 指向错误。
    2. 没有 arguments 对象:需要使用剩余参数(...args)来获取参数列表。
    3. 不能作为构造函数:使用 new 调用会抛出错误。
    4. 没有 prototype 属性
    5. 不能用作 Generator 函数

经典 this 对比示例

const obj = {
value: 'abc',
traditional: function() {
setTimeout(function() {
console.log(this.value); // undefined (this 指向 window 或 undefined)
}, 100);
},
arrow: function() {
setTimeout(() => {
console.log(this.value); // 'abc' (this 继承自 arrow 函数,即 obj)
}, 100);
}
};
obj.traditional();
obj.arrow();

二、解构赋值

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

1. 数组解构
  • 基本用法:按顺序对应。
    const [a, b] = [1, 2]; // a=1, b=2
  • 跳过元素:使用空位。
    const [a, , c] = [1, 2, 3]; // a=1, c=3
  • 默认值:当解构出的值为 undefined 时使用默认值。
    const [a = 5, b = 10] = [1]; // a=1, b=10
  • 剩余模式:使用 ... 将剩余元素放入一个数组。
    const [a, ...rest] = [1, 2, 3, 4]; // a=1, rest=[2,3,4]
2. 对象解构
  • 基本用法:按属性名对应。
    const { name, age } = { name: 'Bob', age: 20 }; // name='Bob', age=20
  • 重命名{ originalKey: newKey }
    const { name: userName } = { name: 'Bob' }; // userName='Bob'
  • 默认值
    const { name = 'Anonymous', age = 0 } = { name: 'Bob' }; // name='Bob', age=0
  • 混合使用:重命名 + 默认值。
    const { name: userName = 'Anonymous' } = {}; // userName='Anonymous'
  • 函数参数解构:非常常用。
    function greet({ name, age = 18 }) {
    console.log(`Hello, ${name}. You are ${age}.`);
    }
    greet({ name: 'Alice' }); // Hello, Alice. You are 18.

三、扩展运算符与剩余参数

1. 扩展运算符
  • 用途:将可迭代对象(如数组、字符串)或对象“展开”为单个元素。
  • 在数组中的使用
    const arr1 = [1, 2];
    const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4] (数组合并)
    console.log(Math.max(...arr1)); // 2 (将数组展开为参数)
  • 在对象中的使用(ES2018):
    const obj1 = { a: 1, b: 2 };
    const obj2 = { ...obj1, c: 3 }; // { a:1, b:2, c:3 } (对象浅拷贝与合并)
2. 剩余参数
  • 用途:将不定数量的参数表示为一个数组。取代了 arguments
  • 在函数参数中的使用
    function sum(...numbers) {
    return numbers.reduce((prev, curr) => prev + curr, 0);
    }
    sum(1, 2, 3); // 6
  • 在解构中的使用
    const [a, b, ...others] = [1, 2, 3, 4, 5]; // a=1, b=2, others=[3,4,5]
    const { a, b, ...restProps } = { a:1, b:2, c:3, d:4 }; // a=1, b=2, restProps={c:3, d:4}

四、新的数据结构

1. MapObject 的区别
特性MapObject
键的类型任意值(函数、对象、基本类型)String 或 Symbol
键的顺序键值对按插入顺序排列无序(ES6后虽有顺序但不保证所有情况)
大小通过 size 属性获取需要手动计算
性能频繁增删键值对的场景下表现更好未优化此场景
默认键从原型链继承可能有默认键

常用APInew Map(), map.set(key, value), map.get(key), map.has(key), map.delete(key), map.size

2. Set 与数组的区别
  • Set 是值的集合,成员的值都是唯一的(自动去重)。
  • 常用APInew Set(), set.add(value), set.has(value), set.delete(value), set.size

应用场景:数组去重。

const uniqueArray = [...new Set([1, 2, 2, 3, 3])]; // [1, 2, 3]
3. WeakMapWeakSet
  • 弱引用:键/值是对象的弱引用,不计入垃圾回收机制。如果键/值对象没有其他引用了,它会被自动回收。
  • 不可迭代:没有 size 属性,无法遍历。
  • 用途:用于存储一些“附属”信息,而不用担心内存泄漏。例如 DOM 元素作为键,存储与之相关的元数据。

五、面向对象与 Class

ES6 的 class 是构造函数的语法糖,更接近传统面向对象语言的写法。

1. 基本语法
class Person {
// 构造函数
constructor(name) {
this.name = name;
}
// 实例方法(挂在原型上)
sayHello() {
console.log(`Hello, I'm ${this.name}`);
}
// 静态方法(类本身的方法)
static isPerson(obj) {
return obj instanceof Person;
}
}
const alice = new Person('Alice');
alice.sayHello(); // Hello, I'm Alice
Person.isPerson(alice); // true
2. 继承

使用 extendssuper

  • super 在构造函数中调用父类构造函数。
  • super 在普通方法中调用父类的方法。
class Student extends Person {
constructor(name, grade) {
super(name); // 必须在使用 this 前调用 super
this.grade = grade;
}
study() {
console.log(`${this.name} is studying.`);
}
// 重写父类方法
sayHello() {
super.sayHello(); // 调用父类的方法
console.log(`I'm in grade ${this.grade}`);
}
}

六、模块化

使用 exportimport 来导出和导入模块。

1. 导出
  • 命名导出
    // math.js
    export const pi = 3.14;
    export function add(a, b) { return a + b; }
    // 或者一起导出
    export { pi, add };
  • 默认导出(一个模块只能有一个):
    // App.js
    export default function() { ... }
    // 或者
    const App = ...;
    export default App;
2. 导入
  • 导入命名导出:需要 {},且名称必须匹配。
    import { pi, add } from './math.js';
    // 重命名
    import { pi as圆周率 } from './math.js';
  • 导入默认导出:不需要 {},可以任意命名。
    import MyApp from './App.js';
  • 全部导入
    import * as math from './math.js'; // 使用 math.pi, math.add

七、其他重要特性

1. 函数参数默认值
function multiply(a, b = 1) {
return a * b;
}
multiply(5); // 5
2. 对象字面量增强
  • 属性简写{ name } 等同于 { name: name }
  • 方法简写{ sayHello() { ... } } 等同于 { sayHello: function() { ... } }
  • 计算属性名{ [propKey]: value }
3. Promise

(在JS异步编程中是核心,此处略,但面试必考)

4. 可选链操作符
  • ?.:如果前面的值是 nullundefined,则表达式短路返回 undefined
    const street = user?.address?.street; // 无需层层判断
5. 空值合并运算符
  • ??:只有当左侧操作数为 nullundefined 时,才返回右侧操作数。
    const value = input ?? 'default'; // 与 `||` 不同,它不会过滤 0, '', false

掌握这些 ES6+ 特性,不仅能让你在面试中对答如流,更能极大地提升你的日常开发效率和代码质量。务必做到理解原理,并能熟练运用。

posted on 2025-12-10 18:57  ljbguanli  阅读(62)  评论(0)    收藏  举报