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

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

JavaScript 相关面试题及答案

  1. JavaScript 的数据类型有哪些?如何区分基本数据类型和引用数据类型?

    JavaScript 的数据类型分为两类:

  • 基本数据类型(值类型):NumberStringBooleanNullUndefinedSymbol(ES6)、BigInt(ES11)。

  • 引用数据类型:Object(包括ArrayFunctionDateRegExp等)。

    区分方式:
    ① 存储方式:基本类型存储值本身,引用类型存储地址(指向堆内存中的对象);
    ② 赋值行为:基本类型赋值是值拷贝,引用类型赋值是地址拷贝(修改新变量会影响原变量)。

  1. nullundefined的区别是什么?分别在什么场景下使用?
  • undefined:表示 “未定义”,变量声明后未赋值、函数无返回值、访问不存在的属性时返回此值。

  • null:表示 “空值”,主动赋值给变量,表示该变量有意为空(如释放对象引用)。

    区别:
    ① 类型不同:typeof undefined返回"undefined"typeof null返回"object"
    ② 转换为数字:Number(undefined)NaNNumber(null)0

  1. 什么是变量提升?函数提升和变量提升有何区别?

    变量提升指 JavaScript 引擎在执行代码前,将变量和函数声明 “提升” 到当前作用域顶部的行为。

    区别:
    ① 函数提升:函数声明整体被提升(可在声明前调用);
    ② 变量提升:仅声明被提升,赋值留在原地(声明前访问返回undefined)。

    示例:

console.log(a); // undefined(变量提升)var a = 1;fn(); // "hello"(函数提升)function fn() { console.log("hello"); }
  1. this关键字在不同场景下的指向是什么?
  • 全局作用域 / 普通函数:指向全局对象(浏览器为window,Node.js 为global),严格模式下为undefined

  • 对象方法:指向调用方法的对象(如obj.fn()this指向obj)。

  • 构造函数(new调用):指向新创建的实例对象。

  • 事件绑定:指向触发事件的元素(如btn.onclickthis指向btn)。

  • 箭头函数:无自身this,继承外层作用域的this(固定不变)。

  • call/apply/bind:手动指定this指向(第一个参数)。

  1. 什么是闭包?闭包有哪些应用场景和缺点?

    闭包指嵌套函数中,内部函数引用外部函数的变量,且内部函数被外部访问,导致外部变量不被销毁的现象。

    应用场景:
    ① 实现私有变量(如计数器:function createCounter() { let n = 0; return () => ++n; });
    ② 保存变量状态(如防抖节流的定时器);
    ③ 模块化(隔离作用域)。

    缺点:
    ① 变量长期驻留内存,可能导致内存泄漏;
    ② 过度使用会增加内存消耗。

  2. 原型和原型链的概念是什么?它们在 JavaScript 中的作用是什么?

  • 原型:每个函数都有prototype属性(原型对象),实例对象通过__proto__(隐式原型)指向该对象,用于共享方法和属性。

  • 原型链:实例访问属性 / 方法时,若自身不存在,会沿__proto__向上查找,直到null,形成的链条即原型链。

    作用:
    ① 实现继承(子实例共享父原型的属性方法);
    ② 节省内存(方法定义在原型上,而非每个实例)。

  1. 什么是事件冒泡和事件捕获?如何阻止事件冒泡?
  • 事件冒泡:事件从触发元素(目标)向上传播到父元素、根元素(由内向外)。

  • 事件捕获:事件从根元素向下传播到触发元素(由外向内)。

    阻止冒泡:
    ① 标准浏览器:event.stopPropagation()
    ② IE 低版本:event.cancelBubble = true

    注意:event.stopImmediatePropagation()还会阻止当前元素后续事件监听器执行。

  1. =====的区别是什么?请举例说明。
  • ==:抽象相等,会自动转换类型后比较(如1 == "1"返回true)。

  • ===:严格相等,不转换类型,类型和值均相同才返回true(如1 === "1"返回false)。

    特殊情况:null == undefinedtruenull === undefinedfalseNaN == NaNfalse(需用isNaN()判断)。

  1. 什么是防抖和节流?它们的应用场景和实现方式是什么?
  • 防抖:触发事件后延迟 n 秒执行,若 n 秒内再次触发则重新计时(如搜索框输入联想)。

    实现:

function debounce(fn, delay) {let timer = null;return (...args) => {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};}
  • 节流:触发事件后,每隔 n 秒最多执行一次(如滚动加载)。

    实现(时间戳版):

function throttle(fn, interval) {let lastTime = 0;return (...args) => {const now = Date.now();if (now - lastTime >= interval) {fn.apply(this, args);lastTime = now;}};}
  1. JavaScript 中如何实现继承?请列举常见方式。
  • 原型链继承:Child.prototype = new Parent(),缺点是共享父类引用属性。

  • 构造函数继承:Parent.call(this),缺点是无法继承父类原型方法。

  • 组合继承:原型链 + 构造函数(Parent.call(this) + Child.prototype = new Parent()),较常用但父构造函数调用两次。

  • 寄生组合继承:Child.prototype = Object.create(Parent.prototype),优化组合继承,避免重复调用。

  • ES6 class继承:class Child extends Parent { constructor() { super() } },语法糖,本质是原型链。

  1. 什么是 Promise?它解决了什么问题?常用方法有哪些?

    Promise 是处理异步操作的对象,有pending(进行中)、fulfilled(成功)、rejected(失败)三种状态,状态一旦改变不可逆转。

    解决的问题:
    ① 回调地狱(嵌套回调导致代码混乱);
    ② 异步操作的同步化表达(链式调用)。

    常用方法:
    then():处理成功 / 失败;
    catch():捕获错误;
    finally():无论成功失败都执行;
    Promise.all():等待所有 Promise 成功;
    Promise.race():取第一个状态改变的 Promise。

  2. 箭头函数和普通函数的区别是什么?

  • this指向:箭头函数无自身this,继承外层this;普通函数this随调用方式变化。

  • 构造函数:箭头函数不能用new调用(无prototype);普通函数可以。

  • arguments:箭头函数无arguments对象(可用剩余参数...args);普通函数有。

  • 写法:箭头函数更简洁(单参数可省括号,单语句可省大括号和return)。

  • 适用场景:箭头函数适合回调(如setTimeout、数组方法),普通函数适合需要动态this的场景(如对象方法)。

  1. 什么是深拷贝和浅拷贝?如何实现深拷贝?
  • 浅拷贝:仅复制对象的表层属性,若属性为引用类型,则复制地址(修改新对象会影响原对象)。

    实现:Object.assign()、扩展运算符{...obj}、数组slice()/concat()

  • 深拷贝:复制对象的所有层级,新对象与原对象完全独立(修改互不影响)。

    实现:
    JSON.parse(JSON.stringify(obj))(缺点:不支持函数、循环引用);
    ② 递归拷贝:

function deepClone(obj, map = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (map.has(obj)) return map.get(obj); // 解决循环引用const clone = Array.isArray(obj) ? \[] : {};map.set(obj, clone);for (const key in obj) {if (obj.hasOwnProperty(key)) {clone\[key] = deepClone(obj\[key], map);}}return clone;}
  1. 数组有哪些常用方法?请分类说明(如增删、遍历、转换等)。
  • 增删:push()(末尾增)、pop()(末尾删)、unshift()(开头增)、shift()(开头删)、splice(index, deleteCount, ...add)(增删改)。

  • 遍历:forEach()map()(返回新数组)、filter()(过滤)、find()(找第一个符合条件元素)、some()/every()(判断)、reduce()(累加)。

  • 转换:join()(转字符串)、split()(字符串转数组,数组无此方法)、toString()

  • 其他:slice()(截取)、sort()(排序)、reverse()(反转)、concat()(合并)。

  1. 什么是异步编程?JavaScript 中实现异步的方式有哪些?

    异步编程指代码不按顺序执行,耗时操作(如网络请求)不阻塞后续代码,完成后通过回调等方式通知执行。

    实现方式:
    ① 回调函数(setTimeout、事件监听);
    ② Promise(链式调用);
    ③ Generator 函数(yield暂停 / 恢复);
    ④ async/await(Promise 语法糖,更接近同步);
    ⑤ 发布 - 订阅模式(事件总线)。

  2. async/await的工作原理是什么?它和 Promise 有什么关系?

    async/await是 ES2017 新增的异步语法,基于 Promise 实现,使异步代码更像同步代码。

    原理:async函数返回 Promise 对象,await后接 Promise,会暂停函数执行,等待 Promise 状态改变后继续。

    关系:
    await只能在async函数中使用;
    await会自动处理 Promise 的成功结果,失败需用try/catch捕获;
    ③ 本质是 Generator 函数和 Promise 的封装,简化异步流程。

  3. 什么是模块化?ES6 模块和 CommonJS 模块的区别是什么?

    模块化指将代码拆分为独立文件,通过导出 / 导入实现复用和隔离。

    区别:

  • 加载时机:ES6 模块是编译时加载(静态分析,支持 tree-shaking);CommonJS 是运行时加载(动态)。

  • 输出:ES6 模块输出值的引用(只读);CommonJS 输出值的拷贝。

  • 语法:ES6 用import/export;CommonJS 用require()/module.exports

  • 环境:ES6 模块浏览器和 Node.js(需配置)支持;CommonJS 主要用于 Node.js。

  1. MapSet有什么特点?它们和普通对象、数组有何区别?
  • Map:键值对集合,键可以是任意类型(对象、基本类型),键唯一,按插入顺序遍历。

    与对象区别:对象键只能是字符串 / Symbol,Map 键类型更灵活;Map 有size属性,对象需手动计算长度。

  • Set:值的集合,值唯一,按插入顺序遍历,无索引。

    与数组区别:数组允许重复值,Set 值唯一;Set 查找值用has(),数组用indexOf/includes

  1. 如何判断一个变量是否为数组?有哪些方法?
  • Array.isArray(arr):最可靠,返回布尔值(推荐)。

  • arr instanceof Array:判断是否为 Array 构造函数的实例(可能受 iframe 影响)。

  • Object.prototype.toString.call(arr) === "[object Array]":准确,可判断多种类型。

  • arr.constructor === Array:不可靠(constructor可被修改)。

  1. 什么是事件循环(Event Loop)?简述其执行过程。

    事件循环是 JavaScript 处理异步操作的机制,流程如下:

    1. 同步代码进入执行栈,立即执行。

    2. 异步任务(宏任务 / 微任务)完成后,分别放入宏任务队列和微任务队列。

    3. 执行栈为空时,先执行所有微任务(如Promise.then)。

    4. 微任务执行完,执行一个宏任务(如setTimeout回调),并触发 UI 渲染。

    5. 重复步骤 3-4,形成循环。

      宏任务:setTimeoutsetInterval、I/O、UI 渲染等。

      微任务:Promise.then/catch/finallyqueueMicrotaskprocess.nextTick(Node.js)。

http://www.dtcms.com/a/331886.html

相关文章:

  • 2025.8.24复习总结
  • WAF 与 SIEM 联动:攻击事件的实时告警与溯源分析流程
  • 3D-R1、Scene-R1、SpaceR论文解读
  • C#:TryGetValue
  • C语言零基础第16讲:内存函数
  • 技术速递|通过 GitHub Models 在 Actions 中实现项目自动化
  • linux 下第三方库编译及交叉编译——MDBTOOLS--arm-64
  • 使用Docker安装Gitea自托管的Git服务
  • 零基础从头教学Linux(Day 12)
  • python+vue扫盲
  • 智能制造综合实训平台数据采集物联网解决方案
  • 备忘录模式及优化
  • 多窗口多烧蚀(Multi-window, Multi-Burn-Rate, MWMBR)
  • 苹果AI战略布局:重新定义智能家居与AI助手的未来
  • TDengine IDMP 基本功能(7. 智能问数)
  • 乘积小于K的子数组
  • flstudio.exe安装教程|FL Studio怎么下载安装?超简单中文指南
  • 状态管理、网络句柄、功能组和功能组状态的逻辑关系
  • 微服务架构概述
  • 《算法导论》第 24 章 - 单源最短路径
  • stm32项目(28)——基于stm32的环境监测并上传至onenet云平台
  • 手机实时提取SIM卡打电话的信令声音-整体解决方案规划
  • Linux新手上路 | 在Ubuntu上Pluma文本编辑器的安装与基本使用
  • 大模型部署基础设施搭建 - Open WebUI
  • 小知识:for of,for in与forEach
  • Stable Diffusion Models are Secretly Good at Visual In-Context Learning
  • localhost:5501与本机ip:5501不同源
  • 服务器的安全检测和防御技术
  • Video-R1论文解读
  • 【深度学习新浪潮】VGGT论文分析