- 浏览器篇
- 1. 前端性能优化的方式
- 2. 函数的节流与防抖
- 3. 深度优先遍历和广度优先遍历
- 4. 深拷贝和浅拷贝
- 5. json.stringfy和json.parse的缺点
- 6. 递归的注意事项、优缺点
- 7. 如何解决内存泄漏
- 8. 垃圾回收机制
- 9. 闭包,优缺点,应用场景
- 10. 强缓存 和 协商缓存
- 11. 输入URL后发生什么
- 12.跨域是如何产生/解决方法
- 13. cookies sessionStorage和localstorage区别
- 14. 常见的HTTP状态码
- 15. 发布订阅模式
- 16. require和import区别
- 19. 和后端通信时 restful api 和get 和post的区别
- 19. 什么是前端工程化、模块化、组件化
- 20. Promise 和 settimeout (事件循环机制)
- REACT篇
- webpack
面试题集合:https://blog.csdn.net/xm1037782843/article/details/80708533
浏览器篇
1. 前端性能优化的方式
- 懒加载 ``` 采用图片懒加载技术,在页面开始加载的时候,不请求真实图片地址,而是用默认图占位,当前页面加载完成后,在根据相关的条件依次加载真实图片(减少页面首次加载http请求的次数)
常见的就是图片的懒加载效果,每次浏览网页的时候,不是一次性将网页中的图片都加载过来,而是将可见范围内的图片加载过来,等到用户浏览下面网页的时候,再开始加载没有加载出来的图片。这样一来,假如用户只对第一屏的内容感兴趣时,那剩余的图片请求就都节省了。 https://www.cnblogs.com/qing-5/p/11343125.html 原理: 先将img标签中的src链接设置为空,将真正的图片链接放在自定义属性(data-src),当js监听到图片元素进入到可视窗口的时候,将自定义属性中的地址存储到src中,达到懒加载的效果。
2. 事件委托<br />
事件委托就是给当前要绑定事件的父元素绑定要绑定的事件,通过事件源来判定当前点击的是哪个元素。这样做是为了减少事件的绑定次数,提高性能,而且还可以实现对未来元素的绑定。 事件代理是指将事件监听器注册在父级元素上,由于子元素的事件会通过事件冒泡的方式向上传播到父节点,因此,可以由父节点的监听函数统一处理多个子元素的事件 利用事件代理,可以减少内存使用,提高性能及降低代码复杂度
4. 减少回流与重绘
1、避免使用层级较深的选择器,或其他一些复杂的选择器,以提高CSS渲染效率 2、避免使用CSS表达式,CSS表达式是动态设置CSS属性的强大但危险方法,它的问题就在于计算频率很快。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次 3、元素适当地定义高度或最小高度,否则元素的动态内容载入时,会出现页面元素的晃动或位置,造成回流 4、给图片设置尺寸。如果图片不设置尺寸,首次载入时,占据空间会从0到完全出现,上下左右都可能位移,发生回流 5、不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间 6、能够使用CSS实现的效果,尽量使用CSS而不使用JS实现 当渲染树中的一部分或者全部因为元素的尺寸、布局、隐藏等改变而需要重新构建的时候,这时候就会发生回流。 每个页面都至少发生一次回流,也就是页面第一次加载的时候。 在回流的时候,浏览器会使渲染树中受到影响的元素部分失效,并重新绘制这个部分的渲染树,完成回流以后,浏览器会重新绘制受到影响的部分元素到屏幕中,这个过程就是重绘
5. 使用缓存
使用cach-control或expires这类强缓存时,缓存不过期的情况下,不向服务器发送请求。强缓存过期时,会使用last-modified或etag这类协商缓存,向服务器发送请求,如果资源没有变化,则服务器返回304响应,浏览器继续从本地缓存加载资源;如果资源更新了,则服务器将更新后的资源发送到浏览器,并返回200响应
6. DNS预解析
通常上网的时候,敲入一个域名地址,电脑会首先向DNS服务器搜索相对应的IP地址,服务器找到对应值之后,会把IP地址返回给你的浏览器,这时浏览器根据这个IP地址发出浏览请求,这样才完成了域名寻址的过程。操作系统会把你常用的域名IP地址对应值保存起来,当你浏览经常光顾的网站时,就可以直接从系统的DNS缓存里提取对应的IP地址,加快连线网站的速度。 浏览器对网站第一次的域名DNS解析查找流程: 浏览器缓存 -> 系统缓存 -> 路由器缓存 -> ISP DNS缓存 -> 递归搜索 实现方法: 1、用meta信息来告知浏览器, 当前页面要做DNS预解析:
2、在页面header中使用link标签来强制对DNS预解析: 适合在以下场景中使用: 电商网站的商品页大量载入不同domain下的商品图,如淘宝 手机网页 大型网站 js或服务端重定向
```
合并请求
压缩资源
资源精简
资源前置加载
资源预热
Gzip
http2协议升级
开启KeepAlive
离线缓存
Canvas 代替 DOM
方案降级
资源内嵌
CDN
图片压缩
优化图片格式
雪碧图
多域名加载资源
资源异步加载
数据分片
首屏内容加载限制
SSR 服务端渲染
离线缓存
升级浏览器内核
Web Worker
异常检测404,白屏检测
容灾节点建设
虚拟列表
想浏览器内核提交优化建议或者代码
2. 函数的节流与防抖
https://blog.csdn.net/Newbie_/article/details/106787008?spm=1001.2014.3001.5501 具体实现
防抖(debounce):在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时,重新触发定时器。
函数的防抖就是通过定时器,来稀释事件触发的频率,只有停止对当前事件的触发,才会执行当前事件要执行的函数。
节流(throttle):规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
区别:防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行。
应用场景:
防抖:
1.search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
2.window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流:
1.鼠标不断点击触发,mousedown(单位时间内只触发一次)
2.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
3. 深度优先遍历和广度优先遍历
深度优先就是自上而下的遍历搜索 广度优先则是逐层遍历
两者的区别
对于算法来说 无非就是时间换空间 空间换时间
深度优先不需要记住所有的节点, 所以占用空间小, 而广度优先需要先记录所有的节点占用空间大
深度优先有回溯的操作(没有路走了需要回头)所以相对而言时间会长一点
深度优先采用的是堆栈的形式, 即先进后出
广度优先则采用的是队列的形式, 即先进先出
4. 深拷贝和浅拷贝
实现:https://www.jianshu.com/p/1fec387a65f7
区别: 浅拷贝只是增加了一个指针指向已存在的内存地址,仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。深拷贝是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存.
首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级
如何实现:
深拷贝:利用json.stringify()和json.parse() / 以递归递归去复制所有层级属性
浅拷贝:Object.assign() / 简单的引用复制
5. json.stringfy和json.parse的缺点
如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
如果对象中存在循环引用的情况也无法正确实现深拷贝;
6. 递归的注意事项、优缺点
优点:代码的表达力很强,写起来简洁。
缺点:空间复杂度高、有堆栈溢出风险、存在重复计算、过多的函数调用会耗时较多等问题。
*** 注意事项 ***
1. 警惕堆栈溢出
如果递归求解的数据规模很大,调用层次很深,一直压入栈,就会有堆栈溢出的风险。
Exception in thread "main" java.lang.StackOverflowError
可以通过在代码中限制递归调用的最大深度的方式来解决这个问题。
例如递归调用超过一定深度(比如 1000)之后,我们就不继续往下再递归了,直接返回报错。
2. 警惕重复计算
7. 如何解决内存泄漏
https://www.cnblogs.com/crazycode2/p/14747974.html
https://blog.csdn.net/weixin_46837985/article/details/114109460
8. 垃圾回收机制
https://segmentfault.com/a/1190000018605776
https://www.cnblogs.com/fanlu/p/11176319.html what/why/when/how
全局变量,系统会在页面关闭时进行释放占用的内存,函数局部变量,会在函数执行完毕时进行释放内存,这就是今天我们的主角:Js的垃圾回收机制。
所有的语言,都需要处理这个过程,比如C语言,需要开发者进行手动,申请与释放内存
而 Javascript 自动帮我们做了内存管理,完成了整个内存管理生命周期,让开发者专注于业务逻辑本身
9. 闭包,优缺点,应用场景
//优点:1.能够读取函数内部的变量 2.让这些变量一直存在于内存中,不会在调用结束后,被垃圾回收机制回收
//缺点:正所谓物极必反,由于闭包会使函数中的变量保存在内存中,内存消耗很大,所以不能滥用闭包,解决办法是,退出函数之前,将不使用的局部变量删除。
//使用闭包的注意点:
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
10. 强缓存 和 协商缓存
https://blog.csdn.net/qq_41648631/article/details/106895782
11. 输入URL后发生什么
https://blog.csdn.net/kongmin_123/article/details/82555936
https://blog.csdn.net/Newbie_/article/details/107212575?spm=1001.2014.3001.5501 简单版+详细版
分为 4 个步骤:
1. 当发送一个 URL 请求时,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器 获得请求对应的 IP 地址。
2. 浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,然后服务器响应并接受客户端的请求,最后由客户端 发出该请求已经被接受的报文。
3. 一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源
4. 此时,Web 服务器提供资源服务,客户端开始下载资源。浏览器接收⽂件( HTML、JS、CSS 、图象等);
然后对加载到的资源( HTML、JS、CSS 等)进⾏语法解析,建立相应的内部数据结构 (如 HTML 的 DOM);
5. 载⼊解析到的资源⽂件,渲染页面,完成。
12.跨域是如何产生/解决方法
.跨域的产生,
浏览器为了保证用户信息的安全,防止恶意的网站窃取数据,所以所有浏览器都实行同源政策,而同源所指的是协议相同、域名相同和端口不同,而产生跨域就是因为同源问题,当其中一个不同时,就导致跨域的产生
13. cookies sessionStorage和localstorage区别
相同点:都存储在客户端
不同点:
1.存储大小
· cookie数据大小不能超过4k。
· sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2.有效时间
· localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
· sessionStorage 数据在当前浏览器窗口关闭后自动删除。
· cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
3. 数据与服务器之间的交互方式
· cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
14. 常见的HTTP状态码
// 2开头 (请求成功)表示成功处理了请求的状态代码。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
// 3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
// 4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
// 5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
15. 发布订阅模式
一般在前端代码中会以异步的形式执行
https://www.bilibili.com/video/BV15h411e7yQ?p=2&spm_id_from=pageDriver
https://zhuanlan.zhihu.com/p/51357583
16. require和import区别
https://zhuanlan.zhihu.com/p/121770261
19. 和后端通信时 restful api 和get 和post的区别
- 区别
https://zhuanlan.zhihu.com/p/228067941
- 简单请求&复杂请求
https://blog.csdn.net/fengyjch/article/details/81020603
- restful 触探(预检请求)
https://segmentfault.com/a/1190000022955509
19. 什么是前端工程化、模块化、组件化
https://www.cnblogs.com/allenlei/p/6195235.html
模块化 commonJS / ES6 module https://blog.csdn.net/xgangzai/article/details/106935104
模块化和组件化一个最直接的好处就是复用,同时我们也应该有一个理念,模块化和组件化除了复用之外还有就是分治,我们能够在不影响其他代码的情况下按需修改某一独立的模块或是组件,因此很多地方我们及时没有很强烈的复用需要也可以根据分治需求进行模块化或组件化开发。
20. Promise 和 settimeout (事件循环机制)
https://www.jianshu.com/p/5b4c4756e461
https://zhuanlan.zhihu.com/p/257069622 (事件循环机制解读)
REACT篇
通用
1. react的设计原理
https://www.cnblogs.com/greatdesert/p/12599220.html 设计思想
2. 函数组件和class组件的区别,优缺点
https://www.jianshu.com/p/e22f941c1439
3. redux原理
https://zhuanlan.zhihu.com/p/50247513
4. 组件间通讯方式
https://www.cnblogs.com/WindrunnerMax/p/14350865.html
父子组件间通信: 父传子,子传父。
兄弟组件之间的通信: 首先需要先将数据从一个兄弟组件传递给他们的公共父组件,然后再由这个公共父组件将数据传递给另一个兄弟组件。
5. 请简述虚拟 dom 与 diff 算法
- 虚拟DOM:也就是常说的虚拟节点,它是通过js的object对象模拟DOM中的节点,然后再通过特定的渲染方法将其渲染成真实的 DOM 节点。
频繁的操作 DOM,或大量造成页面的重绘和回流。
- Diff 算法:把树形结构按照层级分解,只比较同级元素,给列表结构的每个单元添加唯一的 key 值,方便比较
- 虚拟DOM的优势 ``` 传统的开发模式 原生JS或JQ操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程。
虚拟 dom 相当于在 js 和 真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。 用javaScript 对象结构表示 dom 树的结构,然后这个树构建一个真正的 dom树,插到文档当中,当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把所记录的差异应用到步骤1所构建的真正的dom 树上,视图就更新了。 好处是,页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制。
<a name="YRUVv"></a>
#### 6. 高阶函数and高阶组件
高阶组件 1) 本质就是一个函数 2) 接收一个组件(被包装组件), 返回一个新的组件(包装组件), 包装组件会向被包装组件传入特定属性 3) 作用: 扩展组件的功能
- 什么是高阶组件及应用场景
[https://zhuanlan.zhihu.com/p/61711492?utm_source=wechat_session](https://zhuanlan.zhihu.com/p/61711492?utm_source=wechat_session)
<a name="Q0Pg2"></a>
#### 7. 合成事件
[https://zh-hans.reactjs.org/docs/events.html](https://zh-hans.reactjs.org/docs/events.html)
<a name="aDmDm"></a>
#### 8. props和state的区别
数据是向下流动的 props:一般用于父组件向子组件通信,在组件之间通信使用。 state:一般用于组件内部的状态维护,更新组建内部的数据,状态,更新子组件的props等。
<a name="E9p1v"></a>
#### 9. 封装一个组件要注意哪些
- 什么时候需要封装 如果一块内容在项目中出现了两次就要考虑是否应进行封装 一个组件、一个函数、一个css 只要是需要多次使用的都可以考虑封装 封装的组件必须具有高性能,低耦合的特性。
1)可读性。公共组件是团队协作的基础,可读性就显得尤为总要,首先组件命名要语义化,大家看到组件就一目了然,知道该组件的功能是啥;其次我们组件要有一个清晰明了的注释,演示组件用例,属性、参数、方法说明。 2)逻辑功能合理性。哪些功能需要暴露给父组件。我们一般的设计原则是,能在组件内完成的功能,尽量不要暴露给父组件处理。 3 传入数据添加校验 4 处理事件的方法写在父组件中 3)最好从父级传入所需信息性。哪些数据需要父组件传进组件,哪些数据是组件自身拥有,哪些数据要输出给父组件一定要条理清晰。尽量由父组件输入,处理完后根据业务场景决定是否需要输出。 4)样式的一致性。首先组件样式风格要一致;其次组件在不同地方,有不同样式。 5)可扩展性。满足百分之80到90的业务场景,但是一些个性化话的场景,需要组件的大部分功能,但是又有新的需求,这时候再开发一个新的组件没有必要,那么我们就要在原有组件的基础上加功能。这是时候我们就要用到插槽slot来做好预留,来增强组件的扩展性。用this.props.children[0],或者定义一个ReactNode类型的props
<a name="bB3SM"></a>
#### 10. 受控组件和非受控组件
[https://blog.csdn.net/qq_41846861/article/details/86598797](https://blog.csdn.net/qq_41846861/article/details/86598797)
<a name="WTXKf"></a>
#### 11. Fiber
[https://blog.csdn.net/sinat_17775997/article/details/93383254?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4.no_search_link&spm=1001.2101.3001.4242](https://blog.csdn.net/sinat_17775997/article/details/93383254?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4.no_search_link&spm=1001.2101.3001.4242)<br />[https://www.cnblogs.com/xiaochen1024/p/14407624.html](https://www.cnblogs.com/xiaochen1024/p/14407624.html) 有图
<a name="Mcqs0"></a>
## Class 类组件
<a name="uMJ9b"></a>
#### 1. 生命周期
[https://blog.csdn.net/qq_15034541/article/details/117361998](https://blog.csdn.net/qq_15034541/article/details/117361998)<br />[https://blog.csdn.net/zxh2075/article/details/99701784](https://blog.csdn.net/zxh2075/article/details/99701784) 这篇讲得好<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1160418/1623306847692-ece6078a-322e-4392-9338-75943eefc1e7.png#clientId=u7345e374-c76a-4&from=paste&id=u6fc90d5b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=694&originWidth=1761&originalType=url&ratio=2&size=463112&status=done&style=none&taskId=uad2a2386-a0c8-4f37-963e-b7e266ab0c0)
新钩子:<br />[https://react.docschina.org/docs/react-component.html#static-getderivedstatefromprops](https://react.docschina.org/docs/react-component.html#static-getderivedstatefromprops)
getSnapshotBeforeUpdate(prevProps, prevState) 替代了componentWillUpdate() getDerivedStateFromProps(props, state) 替代了componentWillReceiveProps()
<a name="CptfJ"></a>
#### 2. setstate之后发生了什么
[https://blog.csdn.net/qq_39207948/article/details/113803273](https://blog.csdn.net/qq_39207948/article/details/113803273) 这篇讲得清楚,批量更新batchupdate
React 在调用 setstate 后,react 会将传入的参数对象和组件当前的状态 合并,触发调和过程, 在调和过程中,react 会根据新的状态构建 react 元素树重新渲染整个 UI 界面,在得到元素树之后,react 会自动计算新老节点的差异,根据差异对界面进行最小化重新渲染
内存中维护一颗虚拟DOM树,数据变化时(setState),自动更新虚拟 DOM,得到一颗新树,然后 Diff 新老虚拟 DOM 树,找到有变化的部分,得到一个 Change(Patch),将这个 Patch 加入队列,最终批量更新这些 Patch 到 DOM 中。
<a name="gGJIl"></a>
#### 3. setState是同步还是异步
[https://zhuanlan.zhihu.com/p/158725289](https://zhuanlan.zhihu.com/p/158725289)
很多小伙伴会下意识的以为setState是一个异步方法,但是其实setState并没有异步的说法,之所以会有一种异步方法的表现形式,归根结底还是因为react框架本身的性能机制所导致的。因为每次调用setState都会触发更新,异步操作是为了提高性能,将多个状态 合并 一起更新,减少re-render调用.
setState本身并不是一个异步方法,其之所以会表现出一种异步的形式,是因为react框架本身的一个性能优化机制。那么基于这一点,如果我们能够越过react的机制,用setTimeout,可以令setState以同步的形式体现。 componentDidMount(){ setTimeout(()=>{ this.setState({number:3}) console.log(this.state.number) },0) } // 打印出 3
<a name="NNkVy"></a>
## Hooks 函数组件
<a name="t2lbO"></a>
#### 1. useEffect使用方法
[https://blog.csdn.net/glorydx/article/details/114107703](https://blog.csdn.net/glorydx/article/details/114107703)
useEffect第一个参数可以返回一个回调函数,这个回调函数将会在组件被摧毁之前和再一次触发更新时,将之前的副作用清除掉。这就相当于componentWillUnmount。 useEffect去除副作用。我们可能会在组件即将被挂载的时候创建一些不断循环的订阅(计时器,或者递归循环)。在组件被摧毁之前,或者依赖数组的元素更新后,应该将这些订阅也给摧毁掉。(如:手动clearInterval)
- 第二个参数存放变量,当数组存放变量发生改变时,第一个参数,逻辑处理函数将会被执行
- 第二个参数可以不传,不会报错,但浏览器会无线循环执行逻辑处理函数。
- 第二个参数如果只传一个空数组,逻辑处理函数里面的逻辑只会在组件挂载时执行一次 ,不就是相当于 componentDidMount
<a name="Cx6RB"></a>
#### 2. 说出hooks有哪些钩子
[https://blog.csdn.net/chenzhizhuo/article/details/104159910](https://blog.csdn.net/chenzhizhuo/article/details/104159910)
useMemo useMemo和useEffect 的使用基本上一样 优点: 对子组件进行一定程度的优化 在useMemo函数内通过复杂计算获取当前值得时候,不需要再父组件每次更新的时候重新计算,只要在依赖项发生变化的时候计算即可
<a name="XNM08"></a>
#### 3. hooks 的优点和缺点
- **优点**
[https://www.jianshu.com/p/d5e4aa1a568d](https://www.jianshu.com/p/d5e4aa1a568d)
拥有了Hooks,生命周期钩子函数可以先丢一边了。 既然Class都丢掉了,哪里还有this?你的人生第一次不再需要面对this。
- **缺点**
条件判断中不能使用hook [https://zh-hans.reactjs.org/docs/hooks-rules.html](https://zh-hans.reactjs.org/docs/hooks-rules.html)
只能用于函数组件或自定义Hooks中 不能写在条件语句中 不能写在函数组件或自定义Hooks中的函数中
- **hook不能解决的问题**
[https://zh-hans.reactjs.org/docs/hooks-faq.html#which-versions-of-react-include-hooks](https://zh-hans.reactjs.org/docs/hooks-faq.html#which-versions-of-react-include-hooks)
getSnapshotBeforeUpdate,componentDidCatch 以及 getDerivedStateFromError:目前还没有这些方法的 Hook 等价写法,但很快会被添加。
<a name="IdlOd"></a>
#### 5. hooks解决了什么
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1160418/1631543824724-6a694672-b6d4-4b82-a6b7-d54b6109878d.png#clientId=u016e8ef9-8bf9-4&from=paste&height=540&id=pcZMW&margin=%5Bobject%20Object%5D&name=image.png&originHeight=540&originWidth=941&originalType=binary&ratio=1&size=222640&status=done&style=none&taskId=u862555ed-7dc2-43b7-8d3d-6723c7b0343&width=941)<br />[https://blog.csdn.net/weixin_42117093/article/details/106543630](https://blog.csdn.net/weixin_42117093/article/details/106543630)
hooks之前,React存在很多问题 在组件间复用状态逻辑很难 复杂组件变得难以理解,高阶组件和函数组件的嵌套过深。 class组件的this指向问题 难以记忆的生命周期 hooks很好的解决了上述问题,hooks提供了很多方法 useState 返回有状态值,以及更新这个状态值的函数 useEffect 接受包含命令式,可能有副作用代码的函数。 useContext 接受上下文对象(从React.createContext返回的值)并返回当前上下文值, useReducer useState的替代方案。接受类型为(state,action) => newState的reducer,并返回与dispatch方法配对的当前状态。 useCallback 返回一个回忆的memoized版本,该版本仅在其中一个输入发生更改时才会更改。纯函数的输入输出确定性 useMemo 纯的一个记忆函数 useRef 返回一个可变的ref对象,其.current属性被初始化为传递的参数,返回的 ref 对象在组件的整个生命周期内保持不变。
<a name="WxLiT"></a>
#### <br />
<a name="QhRGJ"></a>
#### 7. 自定义hook
[https://www.cnblogs.com/xm0328/p/14421516.html](https://www.cnblogs.com/xm0328/p/14421516.html)
<a name="AiZkc"></a>
## TS 篇
<a name="tYP6K"></a>
#### 1. type和interface的区别
[https://www.cnblogs.com/mengff/p/12936795.html](https://www.cnblogs.com/mengff/p/12936795.html)<br />默认导出方式不同,inerface 支持同时声明,默认导出; 而type必须先声明后导出
<a name="ifoiD"></a>
#### 2. 什么是泛型
[https://blog.csdn.net/semlinker/article/details/106882403/](https://blog.csdn.net/semlinker/article/details/106882403/)<br />[https://www.bilibili.com/video/BV1jK4y1373b?p=3&spm_id_from=pageDriver](https://www.bilibili.com/video/BV1jK4y1373b?p=3&spm_id_from=pageDriver) 视频讲解
简单来说就是类型变量。类型像传递给函数的参数一样传递。
当我们调用 identity
<a name="Hybxt"></a>
#### 3. JS 和 TS 的区别
javascript是一个弱类型语言,Typescript是Javascript的一个超集,最大区别就是Ts提供了类型系统。 TypeScript 只会进行静态检查,如果发现有错误,编译的时候就会报错。 为程序员提前规避了很多错误,而不是等到执行代码的时候才发现错误。
<a name="ydzkx"></a>
# CSS篇
<a name="KFCl6"></a>
#### 1. 元素居中的方法
// 垂直居中(必须和display:inline-block 搭配使用) display:inline-block; vertical-align:middle;
// margin margin:0 auto;
// 使用css3计算的方式居中元素calc position: absolute; top: calc(50% - 50px); left: calc(50% - 150px);
// 使用css3的translate水平垂直居中元素 position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
// 行内元素的垂直居中把height和line-height的值设置成一样的即可 height:40px; line-heigth:40px;
// 让大小不固定元素垂直居中,这个方式将要对其的元素设置成为一个td,float、absolute等属性都会影响它的实现,不响应margin属性; display: table-cell; text-align: center; vertical-align: middle;
<a name="jx2xt"></a>
#### 2. flex的3个参数
<a name="D1SW3"></a>
#### 3. position
static (默认值,即没有定位,遵循正常的文档流对象。) relative :相对其正常位置,移动相对定位元素,它原本所占的空间不会改变。常被用来作为绝对定位元素的容器块。 fixed :相对于浏览器窗口是固定位置。 absolute:相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于: sticky:基于用户的滚动位置来定位。
<a name="xHXc6"></a>
#### 2. css选择器有哪些,选择器的权重的优先级
- !important 表示强制应用该样式,例如:button{ width:150px !important;},与以上的选择器相遇时,强制使用此样式;
- 如果比较后权重相同,那么后者覆盖前者,后渲染的胜出;
- 内联样式 > id选择器样式 > class类/伪类选择器样式 > 伪元素/标签选择器样式>子/相邻选择器
1、ID #id 2、class .class 3、标签 p 4、通用 * 5、属性 [type=”text”] 6、伪类 :hover 7、伪元素 ::first-line 8、子选择器、相邻选择器
三、权重计算规则
- 第一等:代表内联样式,如: style=””,权值为1000。
- 第二等:代表ID选择器,如:#content,权值为0100。
- 第三等:代表类,伪类和属性选择器,如.content,权值为0010。
- 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。
- 通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。
- 继承的样式没有权值。
标准盒模型中width指的是内容区域content的宽度;height指的是内容区域content的高度。 标准盒模型下盒子的大小 = content + border + padding + margin 怪异盒模型中的width指的是内容、边框、内边距总的宽度(content + border + padding);height指的是内容、边框、内边距总的高度 怪异盒模型下盒子的大小=width(content + border + padding) + margin<a name="yBBrX"></a>
#### 3. 盒模型
标准盒模型和怪异盒模型本质上都是一个盒子,它们的区别就是计算宽度和高度的不同。
可以通过属性box-sizing来设置盒子模型的解析模式 box-sizing的三个值: content-box:默认值,border和padding不算到width范围内,可以理解为是W3c的标准模型 border-box:border和padding划归到width范围内,可以理解为是IE的怪异盒模型 padding-box:将padding算入width范围
网页会在第一行加上如下的DOCTYPE 声明 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 如果把这一行注释掉后,那么IE6下就采取的是IE的盒子模型了。也就是说,不管是什么样的IE浏览器还是其它标准的浏览器,都可以在代码前加上DOCTYPE声明而统一的采取W3C的盒子模型
<a name="ps5lM"></a>
#### 4. em 和 rem 区别
(1)em:em是一种相对长度单位,相对于自身元素的字号大小,如果没有设置即参照父容器的字号大小或浏览器默认字号大小。<br /> 举例:如一个div#box的宽度设置为#box{ width:10em },其字号大小#box{ font-size:14px },则此div的宽度为140px。<br />(2)rem: rem是css3的新标准也是一种相对长度单位,其相对于HTML根标签的字号大小。
<a name="YIfOA"></a>
#### 5. bfc
[https://zhuanlan.zhihu.com/p/25321647](https://zhuanlan.zhihu.com/p/25321647)
<a name="BCnDJ"></a>
#### 6. sass 和 less区别
- sass
是一种对css的一种扩展提升,增加了规则、变量、混入、选择器、继承等等特性。可以理解为用js的方式去书写,然后编译成css。比如说,sass中可以把反复使用的css属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。
他们是动态样式语言. 对CSS赋予了动态语言的特性<br />[https://www.cnblogs.com/hope666/p/6791790.html](https://www.cnblogs.com/hope666/p/6791790.html)<br />使用: [https://juejin.cn/post/6875576860462448648](https://juejin.cn/post/6875576860462448648)
- less
[https://blog.csdn.net/Newbie___/article/details/104898436](https://blog.csdn.net/Newbie___/article/details/104898436)
<a name="aSlWF"></a>
#### 7. css工程化解决类名冲突、重复样式等问题
[https://blog.csdn.net/Newbie___/article/details/104898581?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.no_search_link](https://blog.csdn.net/Newbie___/article/details/104898581?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.no_search_link)<br />sass/less [https://blog.csdn.net/Newbie___/article/details/104898436](https://blog.csdn.net/Newbie___/article/details/104898436)
<a name="tBOvm"></a>
#### 7. 移动端页面自适应的方法
[https://www.cnblogs.com/chenyoumei/p/10510321.html](https://www.cnblogs.com/chenyoumei/p/10510321.html)
使用 @media 查询,你可以针对不同的媒体类型定义不同的样式。 @media only screen and (max-width:700px) { .col_sm_1 { width: 25%; height: 100px; } .col_sm_2 { width: 50%; height: 100px; } .col_sm_3 { width: 75%; height: 100px; } .col_sm_4 { width: 100%; height: 100px; } }
@media only screen and (min-width:700px) { .col_lg_1 { width: 25%; } .col_lg_2 { width: 50%; } .col_lg_3 { width: 75%; } .col_lg_4 { width: 100%;} } ———————————————— 上面这几行代码分别设置了在屏幕宽度小于700px时和大于700px时,几个类的样式。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。这时我们设置的应用于不同页面大小的类的样式便生效了。
<a name="fdgEU"></a>
#### 8. 响应式布局
[https://zhuanlan.zhihu.com/p/258341726](https://zhuanlan.zhihu.com/p/258341726)
<a name="nCqV6"></a>
# JS篇
<a name="MWDMY"></a>
#### 1. ES6 - ES12 新特性
[https://zhuanlan.zhihu.com/p/354901519](https://zhuanlan.zhihu.com/p/354901519)<br />[https://blog.csdn.net/qq_41971356/article/details/106972438](https://blog.csdn.net/qq_41971356/article/details/106972438)
let const 解构赋值 字符串模板 函数箭头(语法糖) 数组新增了map() 和 reduce()方法,reduce()会从左至右依次把数组中的元素用reduce()处理,并把处理结果作为下一次reduce的第一个参数 运算符扩展 (…) Promise, Symbol(唯一的值) Set本质与数组类似。不同于Set中只能保存不同的元素,如果元素相同会被忽略。 Map本质是与Object类似的结构。不同在于Object强制规定key值只能是字符串。而Map对象的key可以是任意对象:
Generator函数 generator是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。 Generator函数有两个特征 function命令与函数名之间有一个*号 函数体内部使用yield语句定义不同的内部状态
for…of循环 通过for…of可以循环遍历Generator函数返回的迭代器。
数组新增方法 flat:数组平铺,也可以理解为降维 filter : 返回符合条件的新数组 findIndex : 返回符合条件的数组的索引 every : 所以的条件都满足才返回true some : 只要有一个条件满足就返回true
<a name="OHQUK"></a>
#### 2. Promise
[https://www.runoob.com/w3cnote/javascript-promise-object.html](https://www.runoob.com/w3cnote/javascript-promise-object.html) 菜鸟教程
- 解决了什么问题 : "回调地狱”所说的嵌套其实是指异步的嵌套。它带来了两个问题:可读性的问题和信任问题.
- 有几种状态 :
pending: 初始状态,不是成功或失败状态。 fulfilled: 意味着操作成功完成。 rejected: 意味着操作失败。
- Promise.race() 和 all()的区别
promise.all参数是一个promise的数组,只有当所有的promise都完成并返回成功,才会调用resolve,当有一个失败,都会进catch,被捕获错误,promise.all调用成功返回的结果是每个promise单独调用成功之后返回的结果组成的数组,如果调用失败的话,返回的则是第一个reject的结果. promise.race也会调用所有的promise,返回的结果则是所有promise中最先返回的结果,不关心是成功还是失败
- Promise 和 settimeout 哪个先执行
<a name="lNZDX"></a>
#### 2. var let const 区别
[https://blog.csdn.net/qq_41971356/article/details/106972438](https://blog.csdn.net/qq_41971356/article/details/106972438)<br />用 var 定义的变量存在变量提升,属于全局范围。<br />let 只能在所声明的代码块中使用,外部无法访问,只能先声明变量,才能使用。
1. const 对内存地址的引用,常量是因为无法改变对内存地址的引用。
```javascript
const area = {};
const area = “test" // 错误,不能改值,因为改变了内存地址
area.url="houdunren.com" //正确
console.log(area) // {url:"houdunren.com"} 这样是可以的,因为引用的地址没有发生改变。
{
const area = "后盾人"
console.log(area) // "后盾人" 正确,但只在块级作用域中有效,和全局的那个没有任何关系,是两个不同的常量
}
console.log(area) // {url:"houdunren.com"}
2. js有几种数据类型
https://blog.csdn.net/u013592575/article/details/95087953
https://blog.csdn.net/u013592575/article/details/95087953
3. 事件绑定有哪些方法
https://www.cnblogs.com/hixxcom/p/7151571.html
4. 如何判断数据类型
https://www.cnblogs.com/yi0921/p/6183422.html
5. 如何判断是数组
https://www.cnblogs.com/lingdu87/p/9152806.html
方法一: 使用instanceof方法
instanceof 用于判断一个变量是否某个对象的实例,左边操作数是一个对象,右边操作数是一个函数对象或者函数构造器。原理是通过判断左操作数的对象的原型链上是否具有右操作数的构造函数的prototype属性。
var arr=[];
console.log(arr instanceof Array) //返回true
方法二: 使用constructor方法
constructor 属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。
console.log([].constructor); //Array
console.log({}.constructor == Object); //true
注意:
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array ==object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array。
方法三:ES5定义了Array.isArray:
Array.isArray([]) //true
6. undefined和null区别
https://zhuanlan.zhihu.com/p/31067843
let config = null (引用类型) || {}
let web = undefined (基本类型) || " "
null: Null类型,代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。
undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。
null是javascript的关键字,可以认为是对象类型,它是一个空对象指针,和其它语言一样都是代表“空值”,不过 undefined 却是javascript才有的。undefined是在ECMAScript第三版引入的,为了区分空指针对象和未初始化的变量,它是一个预定义的全局变量。没有返回值的函数返回为undefined,没有实参的形参也是undefined。
javaScript权威指南: null 和 undefined 都表示“值的空缺”,你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。
7. 数组有哪些方法
sort() 方法以字母顺序对数组进行排序:
reverse() 方法反转数组中的元素。
pop() 方法从数组中删除最后一个元素,返回“被弹出”的值:
push() 方法(在数组结尾处)向数组添加一个新的元素,返回新数组的长度:
shift() 方法会删除首个数组元素,返回被“位移出”的字符串:
unshift() 方法(在开头)向数组添加新元素,返回新数组的长度。
既然 JavaScript 数组属于对象,其中的元素就可以使用 JavaScript delete 运算符来删除
splice() 方法可用于向数组添加新项,返回一个包含已删除项的数组:
concat() 方法通过合并(连接)现有数组来创建一个新数组:它总是返回一个新数组。
slice() 方法用数组的某个片段切出新数组。
forEach() 方法为每个数组元素调用一次函数(回调函数)。
map() 方法不会更改原始数组。
filter() 方法创建一个包含通过测试的数组元素的新数组。
every() 方法检查所有数组值是否通过测试。
some() 方法检查某些数组值是否通过了测试。
indexOf() 方法在数组中搜索元素值并返回其位置。
Array.lastIndexOf() 与 Array.indexOf() 类似,但是从数组结尾开始搜索。
find() 方法返回通过测试函数的第一个数组元素的值。
findIndex() 方法返回通过测试函数的第一个数组元素的索引。
Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
- map 和 foreach 的区别 ``` 相同点 都是循环遍历数组中的每一项 forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item、index、arr(原数组) 匿名函数中的this都是指向window
区别 forEach() 没有返回值。 map() 有返回值,返回的是新数组
<a name="AMgTk"></a>
#### 8. 数组去重方法
[https://segmentfault.com/a/1190000016418021?utm_source=tag-newest](https://segmentfault.com/a/1190000016418021?utm_source=tag-newest)
<a name="yIvzq"></a>
#### 9. promise有几种状态
[https://www.cnblogs.com/ZJTL/p/12601134.html](https://www.cnblogs.com/ZJTL/p/12601134.html)
<a name="DvCEs"></a>
#### 10. this指向
[https://blog.csdn.net/zhang6223284/article/details/81288667](https://blog.csdn.net/zhang6223284/article/details/81288667)
当一个函数被调用时,会创建一个活动记录(有时候也成为执行上下文)这个记录会包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this 就是这个记录的一个属性。
this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,
1:在全局作用域下 this对象指向的是window对象
2:在函数作用域下
在非严格模式下: this的指向依旧是window对象
在严格模式下:this的指向是undefined
3:在对象里面 this的指向是当前该对象
new操作符会改变函数this的指向问题,如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
<a name="nXmgh"></a>
#### 11. 箭头函数中的this指向
箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。 箭头函数不适用 this 的四种标准规则,而是在 this 定义的时候保存当前的作用域链,然后顺着当前的作用域链寻找 this,并且只会在作用域链最前端的活动对象或变量对象中寻找(有不理解的可以参考 浅析 javascript 中执行环境,变量对象及作用域链)。简单来说就是箭头函数的 this 是在定义的时候就与对象绑定了,而不是在调用的时候根据调用位置决定。 如果所在的作用域其实是最外层的js环境,因为没有其他函数包裹;然后最外层的js环境指向的对象是winodw对象,所以这里的this指向的是window对象。
<a name="dn9Sn"></a>
#### 12. new做了什么
//1查看 类构造器 的返回值,如果是简单类型,就忽略掉返回值,执行第2步; // 如果是复杂类型,就直接返回return; //2 创造一个空对象 => var obj = {} //3 执行这个函数,让this指向这个空对象=> obj.a =1 //4 运行这个对象 => {a:1}
<a name="enOxw"></a>
#### 13.js的强制类型转换
[https://www.jianshu.com/p/d37cdc717f72](https://www.jianshu.com/p/d37cdc717f72)
<a name="WC41W"></a>
# 通用篇
<a name="kP1Fu"></a>
#### 1. 你在实际开发过程中遇到过什么困难?成功解决过什么难题?
面试问这个问题是为了看你在遇到问题时解决问题的过程,不是你真的解决了什么问题。<br />比如前期做了什么调研,怎么分析问题的核心,怎么去实现方案,最后拿到什么结果。
<a name="xSxQI"></a>
#### 2. 你是如何学习前端的?
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1160418/1625477173468-1d9654f7-50e6-4556-8352-25e4cde6a2b9.png#clientId=uf9fca257-5984-4&from=paste&height=283&id=uf5df5fd0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=566&originWidth=1170&originalType=binary&ratio=1&size=272029&status=done&style=none&taskId=udbe319a4-1640-43e0-8311-8e62797e8a1&width=585)
<a name="JiQng"></a>
# 面试问题
作用域链 [https://www.cnblogs.com/gaosirs/p/10579059.html](https://www.cnblogs.com/gaosirs/p/10579059.html)<br />react和vue有哪些区别 [https://blog.csdn.net/z591102/article/details/108316332](https://blog.csdn.net/z591102/article/details/108316332)<br />ts中的type和interface区别 [https://blog.csdn.net/dtbk123/article/details/107013672/](https://blog.csdn.net/dtbk123/article/details/107013672/)<br />原型链<br />usestate能否写在if语句里 [https://www.h5w3.com/64197.html](https://www.h5w3.com/64197.html)<br />DOM事件流 [https://blog.csdn.net/zhang1600/article/details/112251849](https://blog.csdn.net/zhang1600/article/details/112251849)[
](https://www.cnblogs.com/chenyoumei/p/10510321.html)<br />js继承<br />延迟加载<br />if作用域<br />1. 懒加载的优缺点2. v-dom的流程<br />3. sass有哪些关键命令,如何引用代码块<br />4. mongoDB和mysql的区别<br />6. desktop version 和mobile version 如何区别<br />7. css动画的关键词 <br />计时器不清除会发生什么
setTimeout定时器不清除没有任何影响,
setInterval循环定时器最好是在达成条件时,进行清除,
9. express next 和koa的区别<br />浏览器兼容问题<br />react事件和原生事件区别<br />sass less 预处理<br />跨域是如何产生的,如何解决<br />super
在 constructor 中必须调用 super 方法,因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于 A.prototype.constructor.call(this, props)``。
constructor
state是如何更新的
v-dom如何diff的
暂时性死区
let var const
发布订阅模式
redux原理
hooks的state是如何存储的
ts有哪些类型,泛型用过没
webpack常用的plugin和loader
受控和非受控的区别,为什么要受控https://blog.csdn.net/qq_41846861/article/details/86598797
谈谈高阶组件
react合成事件和原生事件https://juejin.cn/post/6844903502729183239
区别https://www.jianshu.com/p/8d8f9aa4b033
谈谈高阶组件
props更新时会重新render吗
promise和setTimeout执行顺序的问题https://blog.csdn.net/wxl1555/article/details/80054538
hooks解决了什么问题https://blog.csdn.net/good575654643/article/details/104007039
有什么是hooks做不到的
usecallback和usememo的区别