null和undefined
MVC和MVVM
vue2和vue3
webpack
loader
file-loader、url-loader、css-loader、image-loader、babel-loader。。。
plugin
Webpack-merge、speed-measure-Webpack-plugin、size-plugin、HotModuleReplacementPlugin。。。
token的无感刷新
map/forEach/filter等数组处理方法
对象的循环for...in
for in 和for of 的区别(必会)
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of
2、for...in 循环出的是 key,for...of 循环出的是 value
3、注意,for...of 是 ES6新引入的特性。修复了 ES5 引入的 for...in 的不足
4、for...of 不能循环普通的对象,需要通过和 Object.keys()搭配使用
防抖、节流
一、防抖
1、概念
防抖策略(debounce):当事件被触发后,延迟 n 秒后再执行回调,;若在n秒内又被触发,则重新计时。
2、理解
多次触发只执行一次,比如王者荣耀回城,只有经过8秒才能触发回城,8秒途中再次触发回城或中断,都需要重新等待8秒才能回城
3、应用场景
登录、发短信等按钮避免用户点击太快,导致发送了多次请求,需要防抖。
二、节流
1、概念
在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发,把频繁触发变为少量触发。
2、理解
一个周期只执行一次,比如王者荣耀技能,只有经过技能冷却时间,,才能再次使用
3、应用场景
① 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
② 懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;
③ 浏览器input搜索框展示下拉列表,需要节流,也可以使用防抖
防抖是触发间隔大于timer才会触发,所以每次在小于间隔time要清除定时器;
节流是不管time内触发多少次,只会每间隔time时间才会触发一次,所以用return
总结:防抖是限制操作,节流是减少操作
重绘重排
重绘:当元素的一部分属性发生改变,如外观、背景、颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,使元素呈现新的外观叫做重绘。
重排(回流):当 render 树中的一部分或者全部因为大小边距等问题发生改变而需要 DOM 树重新计算的过程
重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)
方法:
1、需要要对元素进行复杂的操作时,可以先隐藏(display:"none"),操作完成后再显示
2、需要创建多个 DOM 节点时,使用 DocumentFragment 创建完后一次性的加入 document
缓存 Layout 属性值,如:var left = elem.offsetLeft; 这样,多次使用 left 只产生一次回流
3、尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
4、避免使用 css 表达式(expression),因为每次调用都会重新计算值(包括加载页面)
5、尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
6、批量修改元素样式:elem.className 和 elem.style.cssText 代替 elem.style.xxx
闭包、内存泄露
闭包(closure)是一个函数以及它所引用环境的组合。创建闭包的常见方式是在一个函数内部创建另一个函数,而该内部函数可以访问外部函数的局部变量,即使外部函数已经执行完毕。
JavaScript内存泄漏指的是在执行一个长期运行的应用程序时,由于缺乏适当的垃圾回收机制,导致不再需要的内存无法被释放,从而累积占用过多内存,最终导致应用崩溃或性能下降的情况。
事件循环机制(eventloop)
宏任务、微任务
在 js 中,任务分为宏任务(macrotask)和微任务(microtask),这两个任务分别维护一个队列,均采用先进先出的策略进行执行!同步执行的任务都在宏任务上执行。
script ==> 宏任务 ==> 微任务
get/post
面试高频:get和post有什么区别?!
GET和POST区别(高频)
1.GET在浏览器回退不会再次请求,POST会再次提交请求
2.GET请求会被浏览器主动缓存,POST不会,要手动设置
3.GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
4.GET请求在URL中传送的参数是有长度限制的,而POST没有
限制
之前问的比较多的是后端那边
5.GET参数通进ORL传递.中OS+妝茬RegWesrbody中
6.GET参数暴露在地址栏不安全,POST放在报文内部更安全
7.GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作
8.GET产生一个TCP数据包;POST产生两个TCP数据包
get和post的选择:
1.私密性的信息请求使用post(如注册、登陆)。
2.查询信息使用get。
浏览器缓存、协商缓存
强缓存
是利用 http 的返回头中的 Expires 或者 Cache-Control 两个字段来控制的,用来表示资源
的缓存时间。
Expires
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,
Expires=max-age + 请求时间,需要和 Last-modified 结合使用。但在上面我们提到过, cache-
control 的优先级更高。 Expires 是 Web 服务器响应消息头字段,在响应 http 请求时告诉浏览
器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
Cache-Control
Cache-Control 是一个相对时间,例如 Cache-Control:3600,代表着资源的有效期是 3600
秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问
题。
Cache-Control 与Expires 可以在服务端配置同时启用或者启用任意一个,同时启用的时候
Cache-Control 优先级高。
协商缓存:
304 在第一次请求时候, 返回状态码200, 和响应头中返回cache-Control, 控制缓存使用
的时间/方式(私有缓存和共享缓存), 在第二次发起请求时, 先查看 max-age 如果过期了, 在请
求头设置 If-None-Match 等于刚刚 Etag 的值, 去后台对比, 如果 etag 值相同证明后端没更新,
所以返回 304 状态, 前端提取本地的缓存继续使用. (也是协商缓存)
Webpack
Webpack 的构建流程是什么(高频必会)
1、初始化参数:从配置文件和 Shell语句中读取与合并参数,得出最终的参数
2、开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
3、确定入口:根据配置中的 entry 找出所有的入口文件
4、编译模块:从入口文件出发,调用所有配置的Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
5、完成模块编译:在经过第四步使上loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
6、输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
7、输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统,在以上过程中,webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用
Webpack 提供的 API 改变 Webpack 的运行结果
Webpack性能优化
Webpack构建流程其中有个步骤是所有的模块进行编译处理,那么我们可以在以下几点上做优化处理,
缩小查找范围,查找的范围缩小从而提升查找效率,可以用alias,extensions等配置缩小范围
减少需要解析的文件,使用noparse配置告诉webpack排除忽略指定文件,不对他们进行解析
避免重复编译第三方库,可以把第三方库单独打包到一个文件中,它不会跟着业务文件一起重新打包,也能提高webpack的构建速度,起到优化作用。那么webpack在对代码进行压缩打包时,如果有多个js文件需要被压缩,她会一个个进行压缩,可以使用thread loader插件来开启多个子进程,采用并行的方式对多个js文件进行压缩打包。
Webpack和Vite
⭐构建速度⭐
Webpack: Webpack的构建速度相对较慢,尤其在大型项目中,因为它需要分析整个依赖图,进行多次文件扫描和转译。
Vite: Vite以开发模式下的极速构建著称。它利用ES模块的特性,只构建正在编辑的文件,而不是整个项目。这使得它在开发环境下几乎是即时的。
⭐开发模式⭐
Webpack: Webpack通常使用热模块替换(HMR)来实现快速开发模式,但配置相对复杂。
Vite: Vite的开发模式非常轻量且快速,支持HMR,但无需额外配置,因为它默认支持。
⭐配置复杂度⭐
Webpack: Webpack的配置相对复杂,特别是在处理不同类型的资源和加载器时。
Vite: Vite鼓励零配置,使得项目起步非常简单,但同时也支持自定义配置,使其适用于复杂项目。
⭐插件生态⭐
Webpack: Webpack拥有庞大的插件生态系统,适用于各种不同的需求。
Vite: Vite也有相当数量的插件,但相对较小,因为它的开发模式和构建方式减少了对一些传统插件的需求。
⭐编译方式⭐
Webpack: Webpack使用了多种加载器和插件来处理不同类型的资源,如JavaScript、CSS、图片等。
Vite: Vite利用ES模块原生支持,使用原生浏览器导入来处理模块,不需要大规模的编译和打包。
⭐应用场景⭐
Webpack: 适用于复杂的大型项目,特别是需要大量自定义配置和复杂构建管道的项目。
Vite: 更适用于小到中型项目,或者需要快速开发原型和小型应用的场景。
⭐打包原理⭐
Webpack: Webpack的打包原理是将所有资源打包成一个或多个bundle文件,通常是一个JavaScript文件。
Vite: Vite的打包原理是保持开发时的模块化结构,使用浏览器原生的导入机制,在生产环境中进行代码分割和优化
webpack也存在静态分析,像tree-shaking、chunk分割在4版本都早已有了,很完善。webpack构建大而全,在开发体验上,所涉及的模块依赖解析及HMR是构建在内存,相较于vite能够支持在开发环境利用浏览器ESModule特性慢而已。rollup是vite在生产环境考虑兼容性所使用的,开发与生产环境都不一致,坑还是不少的。