某知名培训机构内部前端面试题

35 阅读12分钟

1. JS有哪些数据类型,它们的区别有哪些?

JS 数据类型分为基本数据类型引用数据类型

•       基本数据类型:String、Number、Boolean、Null、Undefined、Symbol、BigInt,共7种,存储在栈内存,值不可变,按值传递。

•       引用数据类型:Object(包含Array、Function、Date等),存储在堆内存,栈内存保存堆内存地址,值可变,按引用传递。

2. 数据类型检测的方式有哪些?

1.    typeof:检测基本数据类型(null 会被识别为 object),引用类型除 function 外都识别为 object。

2.    instanceof:检测构造函数的 prototype 是否出现在实例的原型链上,适用于引用类型。

3.    Object.prototype.toString.call() :最准确的检测方式,返回 [object 类型] 格式字符串,可识别所有数据类型。

4.    constructor:通过实例的 constructor 属性指向其构造函数来判断。

3. 介绍下Ajax

Ajax 全称 Asynchronous JavaScript and XML(异步 JavaScript 和 XML),是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分页面的技术。核心是 XMLHttpRequest 对象(或现代的 fetch API),实现异步请求,提升用户体验。流程:创建请求对象→配置请求参数→发送请求→监听状态变化→处理响应数据。

4. 如何判断一个数据是NaN?

5.    Number.isNaN():ES6 新增方法,仅当参数是 NaN 且类型为 Number 时返回 true,避免了全局 isNaN() 的类型转换问题。

6.    value !== value:利用 NaN 是唯一不等于自身的值的特性,这是判断 NaN 的可靠方法。

5. null和undefined的区别

•       undefined:表示变量已声明但未赋值,或对象属性不存在,是 JS 自动赋予的初始值;typeof undefined 返回 undefined。

•       null:表示变量主动赋值为“空值”,代表一个空对象指针;typeof null 返回 object。

•       转换为数值时:Number(undefined) 是 NaN,Number(null) 是 0。

6. 介绍下闭包,在什么场景下使用过?

•       定义:闭包是指有权访问另一个函数作用域中变量的函数,本质是函数作用域链的保留。

•       特性:延长外部函数变量的生命周期,隔离作用域避免变量污染。

•       使用场景:① 封装私有变量(如计数器函数,避免全局变量);② 防抖节流函数的实现;③ 模块化开发中暴露特定方法。

7. 事件委托是什么?如何确定事件源?

•       事件委托:利用事件冒泡机制,将子元素的事件绑定到父元素上,由父元素统一处理。优点是减少事件绑定次数、支持动态添加的子元素。

•       确定事件源:在事件处理函数中,通过 event.target(触发事件的真实元素)获取事件源,兼容低版本 IE 用 event.srcElement。

8. 本地存储与cookie的区别

 

特性本地存储(localStorage/sessionStorage)Cookie
存储大小约 5MB约 4KB
生命周期localStorage 永久存储,sessionStorage 会话结束失效可设置过期时间,默认会话结束失效
与服务器交互不随请求发送到服务器每次请求自动携带到服务器
作用域同源页面共享同源且符合路径、域名规则

9. 简述下ES6的新特性

7.    块级作用域:let、const 关键字。

8.    箭头函数:简化函数写法,无自己的 this。

9.    解构赋值:快速提取数组、对象的属性。

  1. 模板字符串:反引号 ` 包裹,支持换行和变量插值 ${}。

  2. 类与继承:class、extends 关键字,简化原型链写法。

  3. 模块化:import/export 语法。

  4. 新增数据结构:Set、Map。

  5. 异步方案:Promise 对象。

  6. 其他:默认参数、剩余参数 ...、扩展运算符 ... 等。

10. Let、var和const的区别

 

特性varletconst
作用域函数作用域/全局作用域块级作用域块级作用域
变量提升存在,可先使用后声明存在暂时性死区,不可先使用同 let
重复声明允许不允许不允许
赋值可多次赋值可多次赋值声明时必须赋值,且不可修改引用(基本类型不可改,引用类型属性可改)

11. 数组都有哪些方法

  1. 增删改查:push()(尾增)、pop()(尾删)、unshift()(头增)、shift()(头删)、splice()(增删改)、slice()(截取)。

  2. 遍历迭代:forEach()、map()、filter()、reduce()、some()、every()。

  3. 排序与转换:sort()(排序)、reverse()(反转)、join()(转字符串)、concat()(合并数组)。

  4. 其他:indexOf()/lastIndexOf()(查找索引)、includes()(判断是否包含)、find()/findIndex()(查找元素/索引)、flat()(扁平化数组)。

12. JSON如何新增和删除键值对

JSON 本质是符合格式的 JS 对象,操作方式与对象一致:

•       新增键值对:obj.key = value 或 obj['key'] = value。

•       删除键值对:使用 delete obj.key 或 delete obj['key']。

13. 简述下面向对象

面向对象(OOP)是一种编程思想,核心是封装、继承、多态

•       封装:将数据和操作数据的方法封装在对象中,隐藏内部细节,暴露公共接口。

•       继承:子类继承父类的属性和方法,实现代码复用。

•       多态:同一方法在不同对象上有不同的表现形式(JS 中通过重写方法实现)。

JS 是基于原型的面向对象语言,没有类的概念(ES6 class 是语法糖)。

14. 普通函数与构造函数的区别

•       命名规范:构造函数首字母通常大写,普通函数首字母小写。

•       调用方式:构造函数用 new 关键字调用,普通函数直接调用。

•       返回值:构造函数默认返回实例对象(手动返回对象会覆盖);普通函数无 return 时返回 undefined。

•       this ****指向:构造函数中 this 指向新创建的实例;普通函数中 this 指向调用者(全局调用指向 window/global)。

15. 请简述原型,原型链和继承

•       原型(prototype :每个函数都有 prototype 属性,指向原型对象,原型对象包含所有实例共享的属性和方法。

•       原型链:每个实例对象都有 proto 属性,指向其构造函数的 prototype;当访问实例属性时,会依次向上查找原型对象,直到 Object.prototype,这条链式结构就是原型链。

•       继承:JS 中继承基于原型链实现,子类实例的 proto 指向父类的 prototype,从而继承父类的属性和方法;常见方式有原型链继承、构造函数继承、组合继承等。

16. 简述下对Promise的理解以及你在什么情况下使用过

•       Promise 理解:Promise 是解决 JS 异步回调地狱的方案,代表一个异步操作的最终完成(或失败)及其结果值。有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败),状态一旦改变不可逆转。提供 then()、catch()、finally() 方法链式调用。

•       使用场景:① 异步请求(如 axios 基于 Promise 封装,处理接口请求的成功和失败);② 读取文件(Node.js 中 fs.promises 模块);③ 多个异步操作的串行/并行处理(Promise.all()/Promise.race())。

17. 简述下async的用法

async 用于声明异步函数,返回值是一个 Promise 对象;await 关键字只能在 async 函数中使用,用于等待 Promise 执行完成,暂停函数执行直到 Promise 状态变为 fulfilled 或 rejected。

•       成功时:await 返回 Promise 的成功值;

•       失败时:需用 try/catch 捕获异常,否则会抛出错误。

•       作用:将异步代码以同步的写法呈现,比 Promise 链式调用更简洁。

18. 简述下jQuery

jQuery 是一款轻量级的 JS 库,核心思想是 Write Less, Do More(写得更少,做得更多)。它封装了原生 JS 的 DOM 操作、事件处理、Ajax 请求等功能,解决了浏览器兼容性问题。特点:① 简洁的选择器;② 链式调用;③ 丰富的插件生态;④ 动画效果便捷。但随着 Vue、React 等框架的兴起,jQuery 在现代前端开发中使用逐渐减少。

19. 什么是Sass、Less,为什么使用它们

•       Sass/Less:都是 CSS 预处理器,扩展了 CSS 的语法,增加了变量、混合、嵌套、继承等特性,让 CSS 更易维护和复用。Sass 后缀是 .scss(或 .sass),Less 后缀是 .less。

•       使用原因:① 变量:统一管理颜色、字体等样式属性;② 嵌套:模拟 DOM 层级结构,增强代码可读性;③ 混合:复用公共样式片段;④ 继承:减少代码冗余;⑤ 模块化:拆分样式文件,便于维护。

20. JS中call()和apply()方法的区别

call() 和 apply() 都用于改变函数执行时 this 的指向,第一个参数都是 this 要指向的对象。

•       区别:传入参数的方式不同。

◦       call():第一个参数是 this 指向,后续参数是单个参数列表,用逗号分隔。

例:fn.call(obj, arg1, arg2)

◦       apply():第一个参数是 this 指向,第二个参数是参数数组(或类数组对象)。

例:fn.apply(obj, [arg1, arg2])

21. 为什么会造成跨域?

跨域是指浏览器的同源策略限制,当一个请求的协议、域名、端口三者中任意一个与当前页面不同,就会产生跨域。同源策略是浏览器的安全机制,防止不同源的页面之间随意访问数据,避免 XSS、CSRF 等攻击。

22. this有几种指向?

  1. 全局环境:this 指向全局对象(浏览器中是 window,Node.js 中是 global)。

  2. 函数直接调用:非严格模式下 this 指向全局对象,严格模式下 this 是 undefined。

  3. 对象方法调用:this 指向调用该方法的对象。

  4. 构造函数调用:this 指向新创建的实例对象。

  5. call() / apply() / bind() ****调用:this 指向传入的第一个参数。

  6. 箭头函数:没有自己的 this,this 指向箭头函数定义时所在作用域的 this。

  7. 事件处理函数:this 指向触发事件的 DOM 元素。

23. 请说出三种减少页面加载时间的方式

  1. 资源压缩:压缩 JS、CSS、HTML 文件,减小文件体积;压缩图片(WebP 格式、图片压缩工具)。

  2. 资源缓存:设置合理的 HTTP 缓存头(如 Cache-Control、Expires),利用 localStorage 缓存不常变化的静态资源。

  3. 减少 HTTP 请求:合并 CSS/JS 文件,使用雪碧图合并小图标,采用懒加载加载非首屏资源。

  4. CDN 加速:将静态资源部署到 CDN 服务器,就近获取资源,提高加载速度。

24. 什么是JSONP,工作原理是什么?它为什么不是真正的Ajax?

•       JSONP:是一种跨域请求解决方案,全称 JSON with Padding

•       工作原理:利用

•       不是真正的 Ajax:Ajax 基于 XMLHttpRequest 对象实现,而 JSONP 基于

25. 说几种数组去重方式

  1. 利用 Set:[...new Set(arr)],简洁高效,ES6 推荐方法。

  2. 利用 indexOf/includes:遍历数组,判断元素是否已存在于新数组中,不存在则添加。

  3. 利用 filter + indexOf:arr.filter((item, index) => arr.indexOf(item) === index)。

  4. 利用对象属性唯一性:将数组元素作为对象的键,避免重复。

26. 简述下深浅拷贝,并说下如何分别实现,以及使用场景

•       浅拷贝:只复制对象的第一层属性,若属性是引用类型,复制的是地址,修改新对象会影响原对象。

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

◦       使用场景:复制只有基本类型属性的简单对象。

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

◦       实现方法:JSON.parse(JSON.stringify(obj))(缺点:无法复制函数、RegExp 等)、递归手写深拷贝、lodash.cloneDeep()。

◦       使用场景:复制包含引用类型属性的复杂对象(如嵌套对象、数组)。

27. 为什么JS是弱类型语言

弱类型语言的特点是变量类型不固定,支持隐式类型转换。JS 中变量声明时不需要指定类型,赋值后类型可以随时改变;在运算时,JS 会自动将不同类型的值转换为相同类型再计算(如 1 + '2' = '12')。与之相对的是强类型语言(如 Java),变量类型固定,必须显式转换类型。

28. 怎么转换Less为CSS

  1. 使用 Less 官方编译器:安装 Node.js 后,通过 npm 安装 less 包,执行命令 lessc styles.less styles.css 编译。

  2. 构建工具集成:在 Webpack/Vite 等构建工具中配置 less-loader,打包时自动将 Less 转换为 CSS。

  3. 编辑器插件:使用 VS Code 的 Easy LESS 插件,保存 Less 文件时自动生成对应的 CSS 文件。

29. ECharts使用最多的是什么?

ECharts 是百度开源的可视化图表库,使用最多的是各类统计图表的绘制,包括:

  1. 折线图/ 柱状图:用于展示数据的趋势和对比。

  2. 饼图/ 环形图:用于展示数据的占比情况。

  3. 地图:用于展示地理相关的数据分布。

  4. 仪表盘:用于展示关键指标的数值。

核心是通过配置项 option 设置图表的数据源、样式、交互等属性。

30. for循环和map循环有什么区别?

  1. 返回值:for 循环无返回值,需手动操作数组;map 循环返回一个新数组,新数组元素是原数组元素经过回调函数处理后的结果。

  2. 功能:for 循环可用于遍历、修改原数组、跳出循环(break/continue);map 循环主要用于映射转换数组,不能中断循环。

  3. 可读性:map 循环写法更简洁,语义化更强,适合数组的批量转换;for 循环更灵活,适合复杂的遍历逻辑。

31. 请写一个简单的类与继承

 

// 父类class Person {  constructor(name, age) {    this.name = name;    this.age = age;  }  sayHello() {    console.log(我是${this.name},今年${this.age}岁);  }}// 子类继承父类class Student extends Person {  constructor(name, age, grade) {    super(name, age); // 调用父类构造函数    this.grade = grade;  }  study() {    console.log(${this.name}在${this.grade}年级学习);  }}// 实例化const stu = new Student('小明', 12, 6);stu.sayHello(); // 我是小明,今年12岁stu.study(); // 小明在6年级学习

32. 同步与异步的区别?阻塞与非阻塞的区别?

同步与异步

•       同步:代码按顺序执行,前一个任务完成后才执行下一个任务,主线程会被阻塞。例:普通函数调用、alert()。

•       异步:任务不会阻塞主线程,发起后继续执行后续代码,任务完成后通过回调/事件通知结果。例:setTimeout、Ajax 请求。

阻塞与非阻塞

•       阻塞:线程执行任务时,必须等待任务完成才能继续执行其他操作,线程处于等待状态。

•       非阻塞:线程执行任务时,若任务未完成,可立即返回去执行其他操作,无需等待,通过轮询或回调获取任务结果。

•       关系:同步≠阻塞,异步≠非阻塞,它们是不同维度的概念(同步异步描述任务的执行顺序,阻塞非阻塞描述线程的状态)。

33. HTTP是什么?有什么特点?

HTTP 全称 HyperText Transfer Protocol(超文本传输协议),是用于在客户端和服务器之间传输数据的应用层协议,基于 TCP/IP 协议。

•       特点

a.     无状态:协议本身不记录客户端的请求状态,每次请求都是独立的(可通过 Cookie/Session 保持状态)。

b.    无连接:HTTP 1.0 中,每次请求都要建立新的 TCP 连接,请求完成后断开;HTTP 1.1 支持持久连接(Keep-Alive)。

c.     简单快速:请求格式简单,客户端向服务器发送请求方法和路径,服务器返回状态码和数据。

d.    灵活:支持多种数据类型(如文本、图片、视频等)。

34. HTTP协议和HTTPS的区别

 

特性HTTPHTTPS
安全性明文传输,数据易被窃取、篡改加密传输(SSL/TLS 协议),数据安全
端口默认 80默认 443
证书无需证书需要 CA 颁发的 SSL 证书
性能速度快,无加密解密开销速度稍慢,有加密解密过程
资源消耗

35. 原型和继承,prototype,call和apply继承的区别

•       原型继承:将子类的 prototype 指向父类的实例,子类实例可继承父类原型上的属性和方法。缺点:父类的引用类型属性会被所有子类实例共享;无法向父类构造函数传参。

•       call/apply 继承:在子类构造函数中调用父类构造函数,通过 call()/apply() 改变父类 this 指向子类实例,实现父类实例属性的继承。缺点:无法继承父类原型上的方法。

•       组合继承:结合原型继承和 call/apply 继承,既继承父类实例属性,又继承父类原型方法,是最常用的继承方式。

36. 说几种数组和字符串的方法及他们的作用

数组方法

  1. map():遍历数组,返回新数组,元素为回调函数处理结果。

  2. filter():过滤数组元素,返回符合条件的新数组。

  3. reduce():累计计算数组元素,返回最终结果(如求和、求积)。

  4. find():返回数组中第一个符合条件的元素。

字符串方法

  1. split():将字符串按分隔符分割为数组。

  2. indexOf()/includes():查找子字符串是否存在,返回索引或布尔值。

  3. substring()/slice():截取字符串的指定部分。

  4. replace():替换字符串中的指定内容。

37. 箭头函数与普通函数的区别

  1. this ****指向:箭头函数无自己的 this,指向定义时所在作用域的 this;普通函数 this 指向调用者。

  2. 构造函数:箭头函数不能作为构造函数,不能用 new 调用;普通函数可以。

  3. 参数:箭头函数没有 arguments 对象,可使用剩余参数 ...args;普通函数有 arguments。

  4. 原型:箭头函数没有 prototype 属性;普通函数有。

  5. 写法:箭头函数写法更简洁,适合回调函数;普通函数写法更灵活。

38. 什么是JS内存泄露

内存泄露是指程序中已不再使用的内存没有被及时释放,导致内存占用越来越高,最终影响程序性能甚至崩溃。JS 中常见的内存泄露场景:

  1. 意外的全局变量(如未声明的变量)。

  2. 闭包导致的变量未释放。

  3. 未清除的定时器/事件监听器。

  4. DOM 元素被删除但仍有引用(如变量保存了已删除的 DOM 节点)。

39. 如何对网站的文件和资源进行优化

  1. 静态资源优化:压缩 JS/CSS/HTML,图片格式转换(WebP)、图片懒加载、雪碧图合并小图标。

  2. 资源加载优化:使用 CDN 加速,预加载关键资源(preload),预解析 DNS(dns-prefetch)。

  3. 代码优化:减少 HTTP 请求,合并文件;删除无用代码(Tree Shaking);延迟加载非首屏脚本。

  4. 缓存优化:设置强缓存和协商缓存,利用 localStorage 缓存静态数据。

  5. 服务器优化:启用 Gzip/Brotli 压缩,使用 HTTP/2 协议(多路复用)。

40. 简述Ajax的执行过程以及常见的HTTP状态码

Ajax 执行过程

  1. 创建 XMLHttpRequest 对象:const xhr = new XMLHttpRequest()。

  2. 配置请求参数:xhr.open(method, url, async)(method:请求方法;url:请求地址;async:是否异步)。

  3. 设置响应处理函数:xhr.onreadystatechange = function() {},监听 readyState 变化。

  4. 发送请求:xhr.send(data)(POST 请求需传递数据)。

  5. 处理响应:当 readyState === 4 且 status === 200 时,获取响应数据 xhr.responseText。

常见 HTTP 状态码

•       2xx 成功:200(请求成功)、201(创建资源成功)。

•       3xx 重定向:301(永久重定向)、302(临时重定向)、304(资源未修改,使用缓存)。

•       4xx 客户端错误:400(请求参数错误)、401(未授权)、403(禁止访问)、404(资源不存在)。

•       5xx 服务器错误:500(服务器内部错误)、503(服务器不可用)。

41. 预加载和懒加载的区别,预加载在什么时间合适

区别

•       预加载:提前加载未来可能需要的资源(如图片、JS 文件),加载完成后缓存,当用户需要时直接从缓存读取,提升体验。主动加载,会增加首屏加载时间。

•       懒加载:延迟加载非首屏资源,只有当资源进入可视区域时才加载,减少首屏加载时间,提升页面加载速度。被动加载,适用于图片、视频等大量静态资源。

预加载合适的时间

预加载应在首屏资源加载完成后进行,避免抢占首屏资源的带宽,影响首屏渲染速度。可通过 window.onload 事件触发,或在页面空闲时(requestIdleCallback)执行。

42. jQuery选择器有哪些?

jQuery 选择器基于 CSS 选择器,分为以下几类:

  1. 基本选择器:ID 选择器(('#id'))、类选择器(('.class'))、标签选择器((div))、通配符选择器(('div'))、通配符选择器(('*'))。

  2. 层级选择器:后代选择器((parentchild))、子元素选择器(('parent child'))、子元素选择器(('parent > child'))、相邻兄弟选择器($('prev + next'))。

  3. 过滤选择器:基本过滤(:first、:last、:eq(index))、内容过滤(:contains(text))、可见性过滤(:visible、:hidden)。

  4. 属性选择器([attr])('[attr]')、('[attr=value]')。

43. jQuery插入节点的方法

  1. 内部插入

◦       append():在元素内部末尾插入节点。

◦       prepend():在元素内部开头插入节点。

  1. 外部插入

◦       after():在元素外部后面插入节点。

◦       before():在元素外部前面插入节点。

  1. 替换节点:replaceWith():用新节点替换原节点。

  2. 包裹节点:wrap():用指定节点包裹每个匹配元素。

44. Get和Post区别

 

特性GETPOST
请求参数拼接在 URL 后,可见放在请求体中,不可见
数据长度受 URL 长度限制,较小无限制,可传输大量数据
安全性低,参数暴露在 URL高,参数隐藏在请求体
缓存可被浏览器缓存不可被缓存
幂等性幂等(多次请求结果相同)非幂等(多次请求可能产生不同结果)
用途读取数据提交/修改数据

45. 什么是CSRF攻击

CSRF 全称 Cross-Site Request Forgery(跨站请求伪造),是一种网络攻击手段。攻击者诱导用户在已登录目标网站的情况下,访问恶意网站,利用用户的登录状态向目标网站发送伪造的请求,从而执行非用户意愿的操作(如转账、修改密码)。防御措施:① 验证 Referer 字段;② 使用 CSRF Token;③ 验证码验证。

46. 如何遍历一个多维数组?

  1. 递归遍历:遍历数组元素,若元素是数组则递归调用遍历函数,否则处理元素。

 

function traverse(arr) {  arr.forEach(item => {    if (Array.isArray(item)) {      traverse(item);    } else {      console.log(item);    }  });}
  1. 扁平化后遍历:用 flat() 方法将多维数组扁平化为一维数组,再遍历。

 

const arr = [1, [2, [3, 4]]];arr.flat(Infinity).forEach(item => console.log(item));

47. Axios的特性?

Axios 是基于 Promise 的 HTTP 客户端,支持浏览器和 Node.js,核心特性:

  1. 支持 Promise API,可链式调用。

  2. 拦截请求和响应(请求拦截器处理 token,响应拦截器统一处理错误)。

  3. 转换请求和响应数据(如自动转换 JSON 数据)。

  4. 取消请求。

  5. 防止 CSRF 攻击。

  6. 客户端支持防御 XSRF。

  7. 支持多种请求方法(GET、POST、PUT、DELETE 等)。

48. 在地址栏输入一个URL,到页面呈现出来,中间发生了什么?

  1. DNS 解析:将域名转换为对应的 IP 地址。

  2. 建立 TCP 连接:客户端与服务器通过三次握手建立连接(HTTP/1.1 默认为持久连接)。

  3. 发送 HTTP 请求:客户端向服务器发送请求行、请求头、请求体。

  4. 服务器处理请求:服务器解析请求,处理业务逻辑,生成响应数据。

  5. 服务器返回响应:服务器向客户端发送响应行、响应头、响应体(HTML 等资源)。

  6. 关闭 TCP 连接:通过四次挥手关闭连接(若开启 Keep-Alive 则保持连接)。

  7. 浏览器解析渲染页面

◦       解析 HTML 生成 DOM 树;

◦       解析 CSS 生成 CSSOM 树;

◦       结合 DOM 树和 CSSOM 树生成渲染树;

◦       布局(Layout):计算元素的位置和大小;

◦       绘制(Paint):将渲染树绘制到屏幕上。

49. 异步操作的解决方案

  1. 回调函数:最基础的方案,将异步操作的结果处理逻辑传入回调函数,但容易导致回调地狱。

  2. Promise:解决回调地狱,通过 then()/catch() 链式调用,支持多个异步操作的串行/并行处理。

  3. async/await:基于 Promise 的语法糖,以同步写法实现异步操作,代码更简洁易读。

  4. Generator 函数:通过 yield 暂停函数执行,next() 恢复执行,可实现异步流程控制(较少使用)。

50. map和forEach的区别

 

特性mapforEach
返回值返回新数组,元素为回调处理结果无返回值(返回 undefined)
功能映射转换数组,适合生成新数组遍历数组,适合执行操作(如打印、修改原数组)
中断循环无法中断,必须遍历所有元素无法中断(无 break/continue)
性能稍慢(需创建新数组)稍快(无新数组创建)

51. TCP和UDP的区别

 

特性TCPUDP
连接性面向连接(三次握手建立连接)无连接(直接发送数据)
可靠性可靠传输,保证数据有序、不丢失不可靠传输,不保证数据到达
传输方式流式传输,数据无边界数据包传输,数据有边界
拥塞控制有拥塞控制和流量控制无拥塞控制
速度较慢较快
用途文件传输、网页加载、邮件发送视频直播、语音通话、实时游戏

52. BOM和DOM的区别

•       DOM:全称 Document Object Model(文档对象模型),是 HTML/XML 文档的编程接口,将文档解析为树形结构,提供操作元素、属性、事件的方法(如 document.getElementById())。核心是 document 对象。

•       BOM:全称 Browser Object Model(浏览器对象模型),是与浏览器窗口交互的接口,提供操作浏览器窗口、地址栏、历史记录等的方法(如 window.open()、location.href)。核心是 window 对象,DOM 是 BOM 的一部分。

53. 简述下Git操作

Git 是分布式版本控制系统,常用操作:

  1. 初始化仓库:git init。

  2. 克隆仓库:git clone 。

  3. 文件操作:git add (添加到暂存区)、git commit -m "message"(提交到本地仓库)。

  4. 分支操作:git branch(查看分支)、git branch (创建分支)、git checkout (切换分支)、git merge (合并分支)。

  5. 远程操作:git remote add origin (关联远程仓库)、git push -u origin master(推送代码)、git pull(拉取代码)。

  6. 版本回退:git log(查看提交记录)、git reset --hard (回退到指定版本)。

54. 什么是Node.js?

Node.js 是基于 Chrome V8 引擎的 JavaScript 运行时环境,让 JS 可以脱离浏览器运行在服务器端。特点:

  1. 非阻塞 I/O:处理高并发请求性能优异。

  2. 事件驱动:基于事件循环机制,异步处理请求。

  3. 丰富的模块生态:通过 npm 管理大量第三方模块。

  4. 跨平台:支持 Windows、Linux、macOS 等系统。

用途:搭建后端服务器、开发 CLI 工具、构建前端工程化工具(如 Webpack)。

55. 遍历数组,遍历对象,遍历字符串的方法都有哪些?哪些可以打断?

遍历数组

  1. 可打断的方法:for 循环(break/continue)、for...of 循环(break/continue)。

  2. 不可打断的方法:forEach()、map()、filter()、reduce()。

遍历对象

  1. for...in:遍历对象的可枚举属性(包括原型链上的属性),可通过 break 打断。

  2. Object.keys()/Object.values()/Object.entries():返回数组后遍历,可结合 for 循环打断。

遍历字符串

  1. 可打断的方法:for 循环、for...of 循环。

  2. 不可打断的方法:split('').forEach()。

56. 回流和重绘

•       回流(Reflow :当元素的布局属性发生变化(如宽高、位置、DOM 结构),浏览器需要重新计算元素的几何属性和位置,重新构建渲染树,这个过程叫回流。回流代价较高,会触发重绘。

•       重绘(Repaint :当元素的样式属性发生变化(如颜色、背景色),但不影响布局时,浏览器只需重新绘制元素外观,这个过程叫重绘。重绘代价低于回流。

•       触发回流的操作:添加/删除 DOM 元素、改变元素尺寸、改变窗口大小、offsetWidth/offsetHeight 等属性的读取。

•       优化:减少回流次数(如批量修改样式、使用 documentFragment 批量添加 DOM)。

57. 节流和防抖

•       防抖(Debounce :触发事件后,在指定时间内没有再次触发事件,才执行回调函数;若在指定时间内再次触发,则重新计时。适用于搜索框输入联想、窗口大小调整等场景。

 

function debounce(fn, delay) {  let timer = null;  return function(...args) {    clearTimeout(timer);    timer = setTimeout(() => fn.apply(this, args), delay);  };}

•       节流(Throttle :触发事件后,每隔指定时间执行一次回调函数,在指定时间内多次触发只执行一次。适用于滚动加载、鼠标移动、按钮点击等场景。

 

function throttle(fn, interval) {  let lastTime = 0;  return function(...args) {    const now = Date.now();    if (now - lastTime >= interval) {      fn.apply(this, args);      lastTime = now;    }  };}

58. 宏任务和微任务

宏任务和微任务是 JS 异步任务的分类,事件循环中执行顺序为:先执行同步代码****→ 执行所有微任务→ 执行一个宏任务→ 再执行所有微任务,以此循环。

•       宏任务(Macrotask :执行时间较长的任务,包括 setTimeout、setInterval、I/O、UI 渲染、script 整体代码。

•       微任务(Microtask :执行时间较短的任务,包括 Promise.then()/catch()/finally()、async/await、queueMicrotask()、MutationObserver。

59. 什么是装饰器?

装饰器(Decorator)是一种设计模式,用于在不修改原函数/类代码的前提下,动态地为其添加额外功能。ES7 中提出了装饰器语法(目前是提案,需通过 Babel 编译)。

•       类装饰器:用于装饰类,修改类的行为。

•       方法装饰器:用于装饰类的方法,修改方法的执行逻辑。

•       用途:日志记录、性能监控、权限校验等。例如:用装饰器记录函数的执行时间。

60. 什么是迭代器?

迭代器(Iterator)是一种接口,为不同的数据结构提供统一的遍历机制。任何数据结构只要部署了 Iterator 接口,就可以通过 for...of 循环遍历。

•       迭代器的特性:有一个 next() 方法,每次调用返回一个对象 { value: 当前值, done: 是否遍历完成 }。

•       原生支持迭代器的数据结构:数组、字符串、Set、Map。

•       自定义迭代器:通过 Symbol.iterator 属性为对象部署迭代器接口。

61. 什么是前端微服务?

前端微服务是借鉴后端微服务的思想,将大型前端应用拆分为多个独立的、可独立开发、测试、部署的小型应用,每个小型应用称为一个“微应用”。

•       核心特点

a.     独立部署:每个微应用可单独发布,不影响其他微应用。

b.    技术栈无关:不同微应用可使用不同的前端框架(如 Vue、React)。

c.     共享基础资源:共享公共组件、工具库、状态管理等。

d.    运行时集成:通过主应用(基座)加载微应用,实现页面跳转和通信。

•       实现方案:基于 qiankun、single-spa 等框架。