当前位置: 首页 > news >正文

20道JavaScript进阶相关前端面试题及答案

JavaScript 进阶相关面试题及答案

  1. 什么是 ES6 的 Proxy?它有哪些常用拦截方法?适用于哪些场景?

    Proxy 是 ES6 新增的对象,用于创建目标对象的代理,可拦截对象的各种操作(如属性读写、删除等)。

    常用拦截方法:get(读取属性)、set(设置属性)、deleteProperty(删除属性)、hasin操作符)、apply(函数调用)等。

    适用场景:
    ① 数据响应式(如 Vue3 的响应式原理);
    ② 数据校验(限制属性类型或值范围);
    ③ 日志记录(监控对象操作);
    ④ 实现只读对象或私有属性。

  2. Reflect 对象的作用是什么?它与 Proxy 有什么关联?

    Reflect 是 ES6 新增的内置对象,提供了一系列操作对象的方法(如Reflect.getReflect.set),与 Proxy 的拦截方法一一对应。

    作用:
    ① 规范化对象操作(将分散在Object和操作符中的功能集中);
    ② 提供更合理的返回值(如Reflect.set返回布尔值表示操作成功);
    ③ 与 Proxy 配合,在拦截方法中调用默认行为(如handler.get = (target, key) => Reflect.get(target, key))。

    关联:Proxy 的拦截方法中,通过 Reflect 可便捷地触发对象的默认操作,避免手动实现复杂逻辑。

  3. 什么是 Generator 函数?它的工作原理和应用场景是什么?

    Generator 函数是 ES6 的异步编程解决方案,用function*定义,内部用yield暂停执行,返回迭代器对象。

    工作原理:调用 Generator 函数后不立即执行,而是返回迭代器,通过next()方法恢复执行,yield将值传出,next()参数可传入值。

    应用场景:
    ① 异步操作同步化表达(替代回调或 Promise 链式调用);
    ② 生成迭代器(遍历复杂数据);
    ③ 控制函数执行流程(分步执行)。

    示例:

function\* generator() {yield 1;yield 2;return 3;}const iter = generator();console.log(iter.next()); // { value: 1, done: false }
  1. Symbol 类型有什么特性?它的主要用途是什么?

    Symbol 是 ES6 新增的基本数据类型,特点:
    ① 唯一不可变(Symbol('a') !== Symbol('a'));
    ② 不可枚举(for...inObject.keys无法遍历);
    ③ 可作为对象属性名(避免属性名冲突)。

    主要用途:
    ① 定义对象的私有属性(无法被常规方法访问);
    ② 定义常量(确保唯一);
    ③ 扩展内置对象方法(如Symbol.iterator定义迭代器);
    ④ 作为switch语句的 case 值。

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

  • WeakMap:键只能是对象,键与对象的引用是弱引用(不阻止垃圾回收),无法遍历(无sizekeys等方法)。

  • WeakSet:值只能是对象,值与对象的引用是弱引用,无法遍历,值唯一。

    与 Map/Set 的区别:
    ① 引用强度:Weak 系列是弱引用,Map/Set 是强引用;
    ② 可遍历性:Weak 系列不可遍历,Map/Set 可遍历;
    ③ 适用场景:Weak 系列适合临时存储对象关联数据(如 DOM 元素的私有数据),避免内存泄漏。

  1. ES6 的模块化机制中,exportimport有哪些用法?
  • export用于导出模块内容:

  • ① 命名导出(export const a = 1;export { a, b };);

  • ② 默认导出(export default function() {},一个模块只能有一个默认导出)。

  • import用于导入模块内容:

  • ① 导入命名导出(import { a, b as c } from './m.js');

  • ② 导入默认导出(import fn from './m.js');

  • ③ 整体导入(import * as mod from './m.js');

  • ④ 仅执行模块(import './m.js')。

    注意:ES6 模块是静态的,import/export必须位于顶层作用域,不能在条件语句中使用。

  1. 什么是函数柯里化?如何实现柯里化?它的应用场景是什么?

    柯里化指将接收多个参数的函数转换为一系列接收单个参数的函数的过程(如f(a,b,c)f(a)(b)(c))。

    实现示例:

function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args);}return (...nextArgs) => curried.apply(this, \[...args, ...nextArgs]);};}// 使用:const add = curry((a, b, c) => a + b + c); add(1)(2)(3) → 6

应用场景:
① 参数复用(固定部分参数);
② 延迟执行(分步传递参数);
③ 函数组合(构建复杂函数)。

  1. 什么是高阶函数?请举例说明其应用。

    高阶函数指接收函数作为参数或返回函数的函数。

    常见例子:
    Array.prototype.map(接收回调函数);
    setTimeout(接收回调函数);
    ③ 防抖节流函数(返回新函数);
    ④ 高阶组件(React 中接收组件返回新组件)。

    应用价值:
    ① 抽象通用逻辑(如map抽象遍历逻辑);
    ② 增强函数功能(如防抖函数增强原函数);
    ③ 实现函数式编程范式(如compose函数组合)。

  2. JavaScript 的错误处理机制是什么?try/catch/finallythrow的作用是什么?

    JavaScript 通过try/catch/finally捕获和处理错误,throw主动抛出错误。

try {if (!num) throw new Error("数字不存在");console.log(num);} catch (e) {console.error(e.message);} finally {console.log("执行结束");}
  • try:包裹可能出错的代码块。

  • catch:当try中发生错误时,执行此块(接收错误对象)。

  • finally:无论是否出错,都会执行(常用于清理资源,如关闭文件)。

  • throw:手动抛出错误(可是任意类型,通常是Error对象)。

    示例:

  1. 什么是迭代器(Iterator)和可迭代对象(Iterable)?如何自定义迭代器?
const obj = {data: \[1, 2, 3],\[Symbol.iterator]\() {let index = 0;return {next: () => {if (index < this.data.length) {return { value: this.data\[index++], done: false };}return { value: undefined, done: true };}};}};for (const item of obj) { console.log(item); } // 1, 2, 3
  • 可迭代对象:实现Symbol.iterator方法的对象(如数组、字符串、Map、Set),for...of可遍历。

  • 迭代器:Symbol.iterator方法返回的对象,包含next()方法,next()返回{ value: 值, done: 是否完成 }

    自定义迭代器示例(使对象可被for...of遍历):

  1. 什么是 Promise 的链式调用?如何处理 Promise 的错误?

    Promise 的then方法返回新的 Promise,因此可链式调用(前一个then的返回值作为后一个then的参数)。

    错误处理方式:
    then的第二个参数(then(null, onRejected));
    catch方法(更推荐,可捕获链式中所有错误);
    finally前的错误会被后续catch捕获。

    示例:

fetchData().then(data => process(data)).then(result => show(result)).catch(error => handleError(error)) // 捕获所有环节的错误.finally(() => cleanup());
  1. Object.assign和扩展运算符(...)的区别是什么?它们在拷贝对象时有什么局限?
  • 共同点:均用于浅拷贝对象(仅复制表层属性)。

  • 区别:
    Object.assign是函数,可接收多个源对象(Object.assign(target, s1, s2));
    ② 扩展运算符是语法糖,更简洁(const newObj = { ...obj1, ...obj2 })。

    局限:
    ① 无法深拷贝(引用类型属性仅复制地址);
    ② 无法拷贝继承的属性和不可枚举属性;
    ③ 对于Symbol作为键的属性,两者均可拷贝。

  1. 什么是 BigInt?它解决了什么问题?如何使用 BigInt?

    BigInt 是 ES11 新增的基本数据类型,用于表示大于2^53 - 1的整数(JavaScript 中 Number 的最大安全整数)。

    解决的问题:Number 类型无法精确表示大整数(如9007199254740993 === 9007199254740992返回true),BigInt 可精确表示任意大整数。

    使用方式:
    ① 在整数后加n(如123n);
    ② 用BigInt()函数转换(如BigInt("123"))。

    注意:BigInt 不能与 Number 直接运算(需转换类型),支持+-*/(整数除法)等运算符。

  2. 什么是 JavaScript 的内存泄漏?常见的内存泄漏场景有哪些?

    内存泄漏指不再使用的内存未被释放,导致内存占用持续增加的现象。

    常见场景:
    ① 意外的全局变量(如未声明的变量,挂载在window上);
    ② 定时器未清除(setInterval引用的 DOM 已删除但定时器仍运行);
    ③ 事件监听器未移除(如 DOM 元素已删除但事件仍绑定);
    ④ 闭包引用(长期持有不需要的变量);
    ⑤ 未清理的 DOM 引用(如缓存的 DOM 元素已被移除)。

  3. 什么是 IIFE(立即执行函数表达式)?它的作用是什么?

    IIFE(Immediately Invoked Function Expression)指定义后立即执行的函数表达式。

    语法:(function() { ... })()(function() { ... }())

    作用:
    ① 创建独立作用域(避免变量污染全局);
    ② 封装私有变量和方法(仅通过暴露的接口访问);
    ③ 早期模块化的实现方式(如 jQuery 的封装)。

    示例:

(function() {const msg = "hello";window.logMsg = () => console.log(msg);})();logMsg(); // "hello"(外部可访问,msg不可访问)
  1. 什么是尾调用优化?它有什么作用?JavaScript 中如何实现尾调用优化?

    尾调用指函数的最后一步是调用另一个函数(如function f(x) { return g(x); })。

    尾调用优化:引擎在尾调用时不创建新的调用栈帧,而是复用当前栈帧,避免栈溢出(尤其递归场景)。

    作用:优化递归函数的性能,防止深层递归导致的Maximum call stack size exceeded错误。

    实现条件:① 函数内部最后一步是调用函数;② 不访问当前栈帧的变量(纯函数);③ ES6 严格模式下才可能被优化(多数浏览器尚未完全支持)。

  2. 什么是 TypeScript?它相比 JavaScript 有哪些优势?

    TypeScript 是 JavaScript 的超集,添加了静态类型系统,最终编译为 JavaScript。

    优势:
    ① 静态类型检查(编译时发现错误,减少运行时 bug);
    ② 增强代码可读性(类型定义即文档);
    ③ 更好的 IDE 支持(自动补全、重构);
    ④ 支持 ES6 + 特性并向下兼容;
    ⑤ 适合大型项目和团队协作(规范代码,减少沟通成本)。

  3. JavaScript 中的设计模式有哪些?请举例说明单例模式和观察者模式。

    常见设计模式:单例模式、观察者模式、工厂模式、装饰器模式、代理模式等。

  • 单例模式:确保一个类只有一个实例,并提供全局访问点(如弹窗组件、全局状态管理)。

    示例:

class Singleton {constructor() {if (Singleton.instance) return Singleton.instance;Singleton.instance = this;}}const a = new Singleton();const b = new Singleton();console.log(a === b); // true
  • 观察者模式:定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者收到通知(如事件总线、Vue 的响应式)。

    示例:

class Observer {constructor(update) { this.update = update; }}class Subject {constructor() { this.observers = \[]; }add(observer) { this.observers.push(observer); }notify(data) { this.observers.forEach(o => o.update(data)); }}
  1. 什么是 Web Assembly?它与 JavaScript 相比有什么优势?

    Web Assembly(Wasm)是一种低级二进制指令格式,可在浏览器中高效运行,设计用于与 JavaScript 配合。

    优势:
    ① 性能接近原生代码(执行速度比 JavaScript 快,尤其计算密集型任务);
    ② 支持 C/C++、Rust 等语言编译为 Wasm,扩展 Web 能力;
    ③ 内存安全(沙箱环境运行)。

    应用场景:游戏引擎、视频编辑、科学计算等高性能需求场景,与 JavaScript 协同工作(JS 调用 Wasm,Wasm 调用 JS)。

  2. JavaScript 的未来发展趋势有哪些?你了解哪些 ES 的新特性?

    发展趋势:
    ① 性能持续优化(如 JIT 编译增强);
    ② 类型系统增强(TypeScript 普及);
    ③ 更好的异步编程支持;
    ④ WebAssembly 深度融合;
    ⑤ 跨平台能力扩展(如 Node.js、桌面 / 移动端框架)。

    近年 ES 新特性(ES2020+):
    ??空值合并运算符(a ?? b,仅anull/undefined时取b);
    ② 可选链?.obj?.a?.b,避免Cannot read property错误);
    Promise.allSettled(等待所有 Promise 完成,无论成功失败);
    ④ 动态导入import()(返回 Promise,支持条件导入);
    ⑤ 顶层await(模块中直接使用await)。

http://www.lryc.cn/news/621016.html

相关文章:

  • DataHub IoT Gateway:工业现场设备与云端平台安全互联的高效解决方案
  • Git 中切换到指定 tag
  • 电子电路学习日记
  • 嵌入式Linux学习-编译内核源码
  • 17 ABP Framework 项目模板
  • 微信公众号推送文字消息与模板消息
  • ActionChains 鼠标操作笔记
  • 恐鬼症 单机+联机(Phasmophobia)免安装中文版
  • SQL181 第二快/慢用时之差大于试卷时长一半的试卷
  • 【昇腾】VirtualBox虚拟机下搭建Ubuntu 22.04环境给TF卡制卡报读写IO错误的问题处理_20250814
  • 自动化测试|持续集成Git使用详解
  • elasticsearch冷热数据读写分离!
  • 快速搭建python HTTP Server测试环境
  • gitlab的ci/cd变量如何批量添加
  • STL算法【常用的算数生成算法】
  • 分享10个ai生成ppt网站(附ai生成ppt入口)
  • 力扣top100(day03-02)--图论
  • 回流(Reflow)与重绘(Repaint):浏览器渲染性能优化核心
  • SpringMVC请求与响应
  • 【Linux】库制作与原理
  • PyTorch回忆(三)U-net
  • java 学习 贪心 + 若依 + 一些任务工作
  • FTP服务器搭建(Linux)
  • opencv:傅里叶变换有什么用?怎么写傅里叶变换?
  • 软件著作权产生与登记关键点
  • 从单机到分布式:用飞算JavaAI构建可扩展的TCP多人聊天系统
  • 算法基础 第3章 数据结构
  • 数学建模-非线性规划模型
  • 深入理解提示词工程:从入门到精通的AI对话艺术
  • Mybatis实现页面增删改查