面试题(持续更新……)

前端面试题(持续更新)

1.说说你对react的理解?有哪些特性?

React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案
遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效
使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流
帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面
react 类组件使用一个名为 render() 的方法或者函数组件return,接收输入的数据并返回需要展示的内容

特性

JSX语法
单向数据绑定
虚拟DOM
声明式编程
Component

2.说说Real DOM和Virtual DOM的区别?优缺点?

虚拟 DOM 不会进行排版与重绘操作,而真实 DOM 会频繁重排与重绘 虚拟 DOM 的总
损耗是“虚拟 DOM 增删改+真实 DOM 差异增删改+排版与重绘”,真实 DOM 的总损耗是
“真实 DOM 完全增删改+排版与重绘”
真实dom优点是:易用。缺点,效率低,解析速度慢,占用内存高,性能差
虚拟dom优点:方便简单,维护困难,性能提高,跨平台,缺点:无法针对性的极致优
化,首次渲染慢

3.说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

(1)挂载阶段:

constructor() 在 React 组件挂载之前,会调用它的构造函数。
componentWillMount: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调
用。
componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用

(2)更新运行阶段:

componentWillReceiveProps: 在接受父组件改变后的props需要重新渲染组件时用到
的比较多,外部组件传递 频繁的时候会导致效率比较低
shouldComponentUpdate():用于控制组件重新渲染的生命周期,state发生变化,组件
会进入重新渲染的流 程,在这里return false可以阻止组件的更新
render(): render() 方法是 class 组件中唯一必须实现的方法。
componentWillUpdate()*: shouldComponentUpdate返回true以后,组件进入重新渲
染完成之前进入这个函 数。
componentDidUpdate(): 每次state改变并重新渲染页面后都会进入这个生命周期

(3)卸载或销毁阶段:

componentWillUnmount (): 在此处完成组件的卸载和数据的销毁。

4.说说React中setState执行机制?

• 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state, 当需要修改
里面的值的状态需要通过调用setState来改变,从而达到更新组件内部数据的作用
• setState第一个参数可以是一个对象,或者是一个函数,而第二个参数是一个回调函数,用
于可以实时的获取到更新之后的数据
• 在使用setState更新数据的时候,setState的更新类型分成:同步更新,异步更新
• 在组件生命周期或React合成事件中,setState是异步
• 在setTimeout或者原生dom事件中,setState是同步
• 对同一个值进行多次 setState, setState 的批量更新策略会对其进行覆盖,取最后一次的
执行结果

5.说说react的事件机制?

React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等 在React中这套事件机制被称之为合成事件
JavaScript是一门单线程的语言,意味着同一时间内只能做一件事,但是这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环在JavaScript中,所有的任务都可以分为
同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等
异步任务还可以细分为微任务与宏任务
微任务一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前
宏任务的时间粒度比较大,执行的时间间隔是不能精确控制的,对一些高实时性的需求就不太符合

6.React组件之间如何通信?

  1. 父组件向子组件通讯:
    父组件可以向子组件传入props的方式,向子组件进行通讯。

  2. 子组件向父组件通讯:
    props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到⽗组件的作⽤域中。

  3. 兄弟组件通信:
    兄弟组件之间的传递,则父组件作为中间层来实现数据的互通,通过使用父组件传递
    例:组件A – 传值 --> 父组件 – 传值 --> 组件B

  4. 跨层级通讯:
    Context 设计⽬的是为了共享那些对于⼀个
    组件树⽽⾔是“全局”的数据,
    使用context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据
    例如当前认证的⽤户、主题或⾸选语⾔,对于跨越多层的全局数据通过 Context 通信再适合不过。

  5. 发布订阅者模式:
    发布者发布事件,订阅者监听事件并做出反应,我们可以通过引⼊event模块进⾏通信。

  6. 全局状态管理工具:
    借助Redux或者Mobx等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store,并根据不同的事件产⽣新的状态。

7.说说你对受控组件和非受控组件的理解?应用场景?

受控组件,简单来讲,就是受我们控制的组件,组件的状态全程响应外部数据 非受控组件,简单来讲,就是不受我们控制的组件一般情况是在初始化的时候接受外部数据,然后自己在内部存储其自身状态大部分时候推荐使用受控组件来实现表单,因为在受控组件中,表单数据由React组件负责处理如果选择非受控组件的话,控制能力较弱,表单数据就由DOM本身处理,但更加方便快捷,代码量少

8.说说你对fiber架构的理解?解决了什么问题?

解决的问题:
JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行时,另一个线程只能挂起等待;如果 JavaScript 线程长时间地占用了主线程,那么渲染层面的更新就不得不长时间地等待,界面长时间不更新,会导致页面响应度变差,用户可能会感觉到卡顿

理解:
React Fiber 是对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现

主要做了:

  • 为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务
  • 增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行
  • dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行

9.说说react diff的原理是什么?

  1. Diff算法是虚拟DOM的一个必然结果,它是通过新旧DOM的对比,将在不更新页面的情况下,将需要内容局部更新
  2. Diff算法遵循深度优先,同层比较的原则
  3. 可以使用key值,可以更加准确的找到DOM节点

reactdiff算法主要遵循三个层级的策略:

tree层级
conponent 层级
element 层级

tree层不会做任何修改,如果有不一样,直接删除创建
component层从父级往子集查找,如果发现不一致,直接删除创建
element层有key值做比较,如果发现key值可以复用的话,就会将位置进行移动,如果没有,则执行删除创建

10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

中间件(Middleware)是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供
的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功
能共享的目的
redux-thunk :用于异步操作
redux-logger:用于日志记录
中间件内部(middlewareAPI)可以拿到getState和dispatch这两个方法

11.如何使用css实现一个三角形?

css做三角形的方法:首先创建一个div元素,设置div的width和height为0,只用边框宽来
填充,边框样式设置为实线“solid”;然后顶部边框设置颜色,剩下的三个边框的颜色设置为
透明“transparent”值即可。

12.什么是强缓存和协商缓存?

12.1 浏览器缓存(Brower Caching):

是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速
度,降低服务器压力 HTTP 1.0协议中的。简而言之,就是告诉浏览器在约定的这个时间前,
可以直接从缓存中获取资源而无需跑到服务器去获取。 http缓存机制主要在http响应头中设
定,响应头中相关字段为Expires、Cache-Control、Last-Modified、Etag

12.2强缓存:

浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK

12.3协商缓存

协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是
否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从
缓存中读取资源;

13.说说React jsx转换成真实DOM的过程?

react中的jsx语法会通过babel转化为 js代码,以React.createElement函数形式存在,createElement函数返回一个ReactElement函数,ReactElement函数返回一个的虚拟节点,虚拟节点中嵌套虚拟节点,就形成了虚拟DOM,最后通过ReactDOM.render方法转化为真实DOM。babel在转化jsx过程中,会判断首字母的大小写当首字母为小写的时候,会被认为是原生DOM标签, 那么createElement中的第一个参数就是一个字符串,表示标签的名称当首字母为大写的时候,会被认为是组件,那么createElement 第一个参数就是组件的名称,

14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

React-redux是官方react UI绑定层,允许React组件从redux存储中读取数据,并将操作分派到存储以更新的状态。提供了connect,Provider等API,帮助我们连接react和redux,实现的逻辑会更加的严谨高效。
@reduxjs/tookit是对Redux的二次封装,开箱即用的一个高效的Redux开发工具,使得创建store,更新store

15.React render方法的原理,在什么时候会触发?

在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件
类组件调用 setState 修改状态:
函数组件通过useState hook修改状态:

16.React性能优化的手段有哪些?

  1. 组件卸载前进行清理操作
  2. shouldComponentUpdate
  3. React.memo
  4. 使用组件懒加载
  5. 不要使用内联函数定义

17.如何通过原生js实现一个节流函数和防抖函数?

防抖:

1.当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间(非常短的时间);
2.当事件密集触发时,函数的触发会被频繁的推迟;
3.只有等待了一段时间也没有事件触发,才会真正的执行响应函数;

function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this; // 保存this指向
        let args = arguments; // 拿到event对象
        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}

节流:

1.当事件触发时,会执行这个事件的响应函数;
2.如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
3.不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的

function throttled1(fn, delay = 500) {
    let oldtime = Date.now()
    return function (...args) {
        let newtime = Date.now()
        if (newtime - oldtime >= delay) {
            fn.apply(null, args)
            oldtime = Date.now()
        }
    }
}

18.说说webpack中常见的loader?解决了什么问题?

Image-loader 加载并且压缩图片文件
Babel-loader 将es6转换为es5
Css-loader 加载css 支持模块化 压缩 文件导入
Style-loader 把css代码注入到js中 通过dom操作去加载css

css-loader:分析css 模块之间的关系,并合成⼀个css style-loader:把css-loader生成的内容,用style标签挂载到页面的head中 less-loader:开发中,我们也常常会使用less、sass、stylus预处理器编写css样式,使开发效率提高,这里需要使用less-loader raw-loader:在webpack中通过import方式导入文件内容,该loader并不是内置的,所以首先要安装,然后在 webpack.config.js 中进行配置 file-loader:把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地址(字符串) url-loader:可以处理理file-loader中的所有事情,但是遇到图片格式的模块,可以选择性的把图片转成base64格式的字符串,并打包到js中,对小体积的图片比较合适,大图片不合适

19.说说如何借助webpack来优化前端性能?

  1. 优化 loader 配置
  2. 合理使用 resolve.extensions
  3. 优化 resolve.modules
  4. 优化 resolve.alias
  5. 使用 DLLPlugin 插件
  6. 使用 cache-loader
  7. terser 启动多线程
  8. 合理使用 sourceMap
  9. 内联 chunk
  10. 代码分离
  11. 图片压缩
  12. 文件大小压缩
  13. Html文件代码压缩

20.说说javascript内存泄漏的几种情况?

1.script 中存在对DOM/BOM 对象的引用导致
2.Javascript 对象泄漏

  1. 通常由闭包导致,
  2. 定时器

21.为什么虚拟 dom 会提高性能?

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要
的 dom 操作,从而提高性能。
用Js对象表示真实的DOM结构,当状态变化的时候在重新创建一个虚拟DOM树结构,然后
用新的树和旧的树进行比较,记录两棵树差异,把所记录的差异应用到所构建的真正的 DOM
树上,视图就更新了。

22.setState同步和异步

在React18之前 setState本身是同步的,但是在react中对事件处理做了批处理的优化
操作,所以执行起来是一个异步操作
在React18之后 setState本身是同步的 所有的setState都做了批处理优化操作 所以所有
的setState都是异步的
使setState从异步变成同步的方法
react18之前 : setState的第二个参数(回调函数)拿到setState之后的结果、通过
在settimeout中 执行setState 拿到结果
react18之后 : setState的第二个参数(回调函数)拿到setState之后的结果、通过
flushSync 执行setState操作 随后就可以立马拿到结果

22.1批处理的好处

  1. 合并不必要的更新,减少更新流程调用次数
  2. 状态按顺序保存下来,更新时不会出现「竞争问题」
  3. 最终触发的更新是异步流程,减少浏览器掉帧可能性

23. 说说你对react hook的理解?

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
每调用useHook一次都会生成一份独立的状态
通过自定义hook能够更好的封装我们的功能
编写hooks为函数式编程,每个功能都包裹在函数中,整体风格更清爽,更优雅
hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks能够解决大多数问题,并且还拥有代码复用机制,因此优先考虑hooks

24.说说Connect组件的原理是什么

在原应用组件上包裹一层,使原来整个应用成为Provider的子组件,接收Redux的store作为props,通过context对象传递给子孙组件上的connect,它真正连接 Redux 和 React,它包在我们的容器组件的外一层,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件
原理:
首先传入mapStateToPropsmapDispatchToProps,然后返回一个生产Component的函数(wrapWithConnect),然后再将真正的Component作为参数传入wrapWithConnect,这样就生产出一个经过包裹的Connect组件,该组件具有:
(1)通过props.store获取祖先Componentstore
(2)props包括statePropsdispatchPropsparentProps,合并在一起得到nextState,作为props传给真正的Component
(3)componentDidMount时,添加事件this.store.subscribe(this.handleChange),实现页面交互
(4)shouldComponentUpdate时判断是否有避免进行渲染,提升页面性能,并得到nextState
(5)componentWillUnmount时移除注册的事件this.handleChange
25.说说react 中jsx语法糖的本质?
jsx是JavaScript的一种语法扩展,它跟模板语言很接近,但是它充分具备JavaScript的能力
JSX就是用来声明React当中的元素,React使用JSX来描述用户界面
JSX语法糖允许前端开发者使用我们最熟悉的类HTML标签语法来创建虚拟DOM在降低学习
成本

26.说说AMD、CMD、commonJS模块化规范的区别?

CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。
ADM、异步加载:因为面向浏览器端,为了不影响渲染肯定是异步加载。依赖前置:所有的依赖必须写在最初的依赖数组中,速度快,但是会浪费资源,预先加载了所有依赖不管你是否用到
CMD、需要的时候去请求而不是先加载再请求

27.说说package.json中版本号的规则?

主号.次号.修补号
1.指定版本号
2.大于version 版本号
3.大于等于version版本号
4.小于version版本号
5.小于等于version版本号
6.~version 右侧任意
7.^version 从左向右,第一个非0号的右侧任意

28.说说你对koa中洋葱模型的理解?

Koa 的洋葱模型指的是以 next() 函数为分割点,先由外到内执行 Request 的逻辑,再由内到外执行 Response 的逻辑。通过洋葱模型,将多个中间件之间通信等变得更加可行和简单
在洋葱模型中,每一层相当于一个中间件,用来处理特定的功能, 也就是说每一个中间件都有两次处理时机

29.说说你对webSocket的理解?

理解
WebSocketHTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)
它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
Websocket是一个持久化的协议
原理
websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
websocket出现之前,web交互一般是基于http协议短连接或者长连接
websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"

30.Vue中自定义指令的理解,应用场景有哪些?

指令系统是计算机硬件的语言系统,也叫机器语言,它是系统程序员看到的计算机的主要属性。因此指令系统表征了计算机的基本功能决定了机器所要求的能力
注册一个自定义指令有全局注册与局部注册
全局注册主要是通过Vue.directive方法进行注册
Vue.directive第一个参数是指令的名字(不需要写上v-前缀),第二个参数可以是对象数据,也可以是一个指令函数
局部注册通过在组件options选项中设置directive属性
然后你可以在模板中任何元素上使用新的 v-focus property,如下:

  • 表单防止重复提交
  • 图片懒加载
  • 一键 Copy的功能
  • 拖拽指令、
  • 页面水印、
  • 权限校验

31.大文件如何做断点续传?

分片上传

  1. 将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;
  2. 初始化一个分片上传任务,返回本次分片上传唯一标识;
  3. 按照一定的策略(串行或并行)发送各个分片数据块;
  4. 发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件

断电续传

断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度

32.原生js如何实现上拉加载下拉刷新?

上拉加载:
获取滑动内容外部盒子高度:document.querySelector(“.container”).clientHeight
获取整个内容的高度:document.querySelector(“.ul”).scrollHeight
获取卷曲出去的高度:let tops = document.querySelector(“.container”).scrollTop
外部盒子高度+卷曲出去的高度>=内容的高度 - 离底部距离高度(自定义)
监听滑动事件scroll 当满足以上条件时执行异步请求,这里需要加一个节流,当触发是禁止再
次触发,等到异步事件加载完毕后,才允许再次上拉触发。
下拉刷新:
监听touchstart、touchmove、touchend三个事件
通过touchstart记录手指触摸时位置
通过touchmove记录向下滑动的距离,同时通过设置transform:translateY(x)来设置内容向下移动,控制滑动距离到达某个值时,禁止页面再做滑动
通过touchend记录手指离开事件,对滑动距离达到限定值时,做刷新请求数据处理,未到限定值时自动回弹translateY(0px),并添加过渡动画

33.说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?

CSS像素(css pixel, px): 适用于web编程,在 CSS 中以 px 为后缀,是一个长度单位
设备像素(device pixels),又称为物理像素指设备能控制显示的最小物理单位,不一定是一
个小正方形区块,也没有标准的宽高,只是用于显示丰富色彩的一个“点”而已
设备独立像素(Device Independent Pixel):与设备无关的逻辑像素,代表可以通过程序控
制使用的虚拟像素,是一个总体概念,包括了CSS像素
dpr(device pixel ratio),设备像素比,代表设备独立像素到设备像素的转换关系,
ppi (pixel per inch),每英寸像素,表示每英寸所包含的像素点数目,更确切的说法应该是
像素密度。数值越高,说明屏幕能以更高密度显示图像
区别:
无缩放情况下,1个CSS像素等于1个设备独立像素
设备像素由屏幕生产之后就不发生改变,而设备独立像素是一个虚拟单位会发生改变
PC端中,1个设备独立像素 = 1个设备像素 (在100%,未缩放的情况下)
在移动端中,标准屏幕(160ppi)下 1个设备独立像素 = 1个设备像素
设备像素比(dpr) = 设备像素 / 设备独立像素
每英寸像素(ppi),值越大,图像越清晰

34.谈谈你对BFC的理解?

BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则 BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素

35.说说TCP为什么需要三次握手和四次握手?

防止旧的重复连接引起连接混乱问题

36.react新出来两个钩子函数是什么?和删掉的will系列有什么区别

新生命周期中新增了两个钩子,分别为getDerivedStateFromProps(从props中得到衍生的state)和getSnapshotBeforeUpdate。
区别
1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替

37.最少说出三种前端清除浮动的方法?

  1. 额外标签法:在需要清除浮动的元素前面加空 div 并设置 clear 为 both
  2. 浮动引起的父元素高度塌陷时,设置父元素 overflow 属性为hidden或auto
  3. after 伪元素清除法浮动

38.说说你对git rebase 和git merge的理解?区别

1、rebase把当前的commit放到公共分支的最后面,merge把当前的commit和公共分支合并在一起;
2、用merge命令解决完冲突后会产生一个commit,而用rebase命令解决完冲突后不会产生额外的commit。

39.在使用redux过程中,如何防止定义的action-type的常量重复?

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

40.调和阶段setState干了什么?

(1)代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
(2)经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
(3)在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
(4)在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

41.props和state相同点和不同点?

props:

props是一个从外部传进组件的参数,由于React具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据,它是不可改变的,如果想要改变它,只能通过外部组件传入新的props来重新渲染子组件,否则子组件的props和展示形式不会改变,props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数

state:

state主要作用是用于组件保存,控制及修改自己的状态,它只能在constructor中初始化,state是可以被改变的,state放改动的一些属性,比如点击选中,再点击取消,类似这种属性就放入带state中,注意:没有state的叫做无状态组件,多用props少state,多写无状态组件,注意:修改state的值时,必须通过调用setState方法,当我们调用this.setState方法时,React会更新组件的数据状态,并且重新调用render方法

42.shouldComponentUpdate有什么作用?

shouldComponentUpdate () 的返回值用于判断 React 组件的输出是否受当前 state 或props 更改的影响,当 props 或 state 发生变化时shouldComponentUpdate () 会在渲染执行之前被调用。

43.在虚拟dom计算的时候diff和key之间有什么关系?

key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。

44.React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?

在reactJS中props.children不一定是数组
有三种可能 :
1当前组件没有子节点数据类型就是undefined,
2有一个子节点数据类型就是object 。
3 有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react资深提供了一个react.children.map()方法,可以安全遍历子节点对象。

45.谈谈你对immutable.js的理解?

Immutable.js采用了 持久化数据结构 ,保证每一个对象都是不可变的,任何添加、修改、删除等操作都会生成一个新的对象,且通过 结构共享 等方式大幅提高性能。

46.redux中同步action与异步action最大的区别是什么?

同步: Redux的教程中反复使用todo列表的例子,那就是个典型的同步action,每当disptach action时,state就会被立即更新[当然setState是异步的]
异步: 一般异步处理都会使用中间件,比如redux-thunk或者redux-saga,他们做的事情是包装dispatch,request action由view触发,receive action由这些中间件触发

47.redux-saga和redux-thunk的区别与使用场景?

redux-thunk:通过执行action中的函数实现业务逻辑,没有拓展API
redux-saga:通过定义saga函数进行监控,同时提供一些常用的API
redux-thunk将部分异步处理业务逻辑写在action中,redux-sagasaga则是放在监控的函数中。

48.CDN的特点及意义?

cdn 内容分发网络。
CDN的功能特点:
(1)节省骨干网带宽,减少带宽需求量;
(2)提供服务器端加速,解决由于用户访问量大造成的服务器过载问题;
(3)服务商能使用Web
Cache技术在本地缓存用户访问过的Web页面和对象,实现相同对象的访问无须占用主干的出口带宽,并提高用户访问因特网页面的相应时间的需求;
(4)能克服网站分布不均的问题,并且能降低网站自身建设和维护成本;
(5)降低“通信风暴”的影响,提高网络访问的稳定性
意义
使用CDN可以获取一些好处,无论它们是公有CDN还是提供静态内容的私有CDN,你的里程
可能会有所不同,具体取决于通过CDN传递的流量以及你产生的流量。

49.![] == ![],![] == [],结果是什么?为什么?

①、根据运算符优先级 ,! 的优先级是大于 == 的,所以先会执行 ![]
②、根据上面提到的规则(如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数
值——false转换为0,而true转换为1),则需要把 false 转成 0
③、根据上面提到的规则(如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较,如果对象没有valueOf()方法,则调用 toString())
④、根据上面提到的规则(如果一个操作数是字符串,另一个操作数是数值,在比较相等性之
前先将字符串转换为数值)

50.什么是闭包,应用场景是什么?

闭包就是能够读取其他函数内部变量的函数,说白了闭包就是个函数,只不过是处于其他函数内部而已。
1.访问函数内部的变量
2.防止函数内部的变量执行完城后,被销毁,使其一直保存在内存中。

51.谈谈你是如何做移动端适配的?

[flex弹性布局]
[百分比]
[用框架搭建页面]
[viewport适配]
[媒体查询media]
[rem+viewport缩放(也成为1px适配)]

52.移动端1像素的解决方案?

  1. 移动端1像素的解决方案?
  2. 伪类+transform
  3. viewport + rem
  4. border-image
  5. background-image
  6. postcss-write-svg
    总结
    0.5px,相信浏览器肯定是会慢慢支持的,目前而言,如果能用的话,可以hack一下。对于老项目,建议采用transform+伪类。新项目可以设置viewport的scale值,这个方法兼容性好。postcss-write-svg简单易用,仅适合直线,圆角建议用transform+伪类实现

53.弹性盒中的缩放机制是怎样的?

弹性盒中的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉
害,且不支持负值; 而flex-shrink属性定义项目的缩小比例,默认值为1,数值越大,缩小越
厉害,同样不支持负值;

54.知道react里面的createPortal么,说说其使用场景?

Portal 将提供一种将子节点渲染到 DOM 节点中的方式,该节点存在于 DOM 组件的层次结构之外。
因此 Portals 适合脱离文档流(out of flow) 的组件,特别是 position: absolute 与 position: fixed的组件。比如模态框,通知,警告,goTop 等

55.如何解决react页面不刷新?

  1. 深拷贝或者改变引用类型数据的地址

  2. Key最好不用index

  3. 在this.setState中使用一个回调来获取一个新的值

  4. 不要直接修改store中的值

  5. 在render中判断state.value值不等于空,再加载子组件

56. 说说对React refs 的理解?应用场景?

创建ref的形式有三种:
1.传入字符串,使用时通过 this.refs.传入的字符串的格式获取对应的元素
2.传入对象,对象是通过 React.createRef() 方式创建出来,使用时获取到创建的对象中存在 current 属性就是对应的元素
3.传入hook,hook是通过 useRef() 方式创建,使用时通过生成hook对象的 current 属性就是对应的元素

在某些情况下,我们会通过使用refs来更新组件,但这种方式并不推荐,更多情况我们是通过props与state的方式进行去重新渲染子元素

但下面的场景使用refs非常有用:
1.对Dom元素的焦点控制、内容选择、控制
2.对Dom元素的内容设置及媒体播放
3.对Dom元素的操作和对组件实例的操作
4.集成第三方 DOM 库

57.说说你对高阶组件的理解?应用场景有哪些?

如果一个函数 接受一个或多个函数作为参数或者返回一个函数 就可称之为 高阶函数。
什么是React高阶组件:一个组件的参数是组件,并且返回值是一个组件,我们称这类组件为高阶组件
withRouter() memo() react-redux中connect方法是高阶组件

58.函数组件中如何使用useReducer

创建初始值的状态initialState
创建所有对状态的操作reducer(state,action)
传给useReducer,得到读和写的接口
调用写({‘type’:‘操作类型’})
useReducer 接受的第一个参数是一个函数,我们可以认为它就是一个 reducer , reducer 的参数就是常规 reducer 里面的 stateaction ,返回改变后的 state , useReducer 第二个参数为 state 的初始值 返回一个数组,数组的第一项就是更新之后 state 的值 ,第二个参数是派发更新的 dispatch 函数。

59.Vue组件通信?

1.父组件通过 props 向子组件传递数据,子组件通过 e m i t 和父组件通信 2. r e f :这个属性用在子组件上,指向子组件的实例,可以通过实例来访问组件的数据和方法 3. emit 和父组件通信 2.ref:这个属性用在子组件上,指向子组件的实例,可以通过实例来访问组件的数据和方法 3. emit和父组件通信2.ref:这个属性用在子组件上,指向子组件的实例,可以通过实例来访问组件的数据和方法3.emit 绑定一个自定义事件,当这个事件被执行的时候就会将参数传递给父组件,而父组件通过v-on监听并接收参数
4.eventBus事件总线($emit / $on)

60.说说React生命周期中有哪些坑?如何避免?

  • getDerivedStateFromProps 容易编写反模式代码,使受控组件和非受控组件区分模糊
  • componentWillMountReact 中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到 componentDidMount
  • componentWillReceiveProps 同样也被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。
  • shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。
  • componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdatecomponentDidUpdate 改造使用。
    如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug
    如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加。

61.说说你对promise的了解?

Promise是ES6中的新增的异步处理方法主要是用于解决ES5中使用回调函数产生的地狱回调的问题
Promise有三种状态,pedding准备中,fullfiilled已完成, rejected失败
状态只能有准备中=>已完成 或 准备中=>失败执行resolve参数方法会调用then方法,执行reject参数方法调用catch方法,
then方法执行成功后调用的方法,catch方法执行失败调用的方法
all() 参数是个数组,执行多个Promise对象,必须所有的对象状态执行完后才会变成已完成的状态
race()方法 执行多个Promise对象,只要有一个对象状态是已完成,对象的状态就是已完成为了解决 Promise 的问题,async、await 在 ES7 中被提了出来
async、await 函数写起来跟同步函数一样,需要接收 Promise 或原始类型的值

62.说说JavaScript中的数据类型?存储上的差别?

基本类型:Number、String、Boolean、Undefined、null、symbol
复杂类型统称为Object
Object
Array
Function
基本数据类型和引用数据类型存储在内存中的位置不同:
基本数据类型存储在栈中
引用类型的对象存储于堆中

63.从浏览器地址栏输入url到显示页面的步骤?

用户在浏览器中输入url地址
浏览器解析域名得到服务器ip地址
TCP三次握手建立客户端和服务器的连接
客户端发送HTTP请求获取服务器端的静态资源
服务器发送HTTP响应报文给客户端,客户端获取到页面静态资源
TCP四次挥手关闭客户端和服务器的连接
浏览器解析文档资源并渲染页面

64.说说react router有几种模式?实现原理?

React Router对应的hash模式和history模式
路由描述URL 与 UI之间的映射关系,这种映射是单向的,
即 URL 变化引起 UI 更新(无需刷新页面)
以hash模式为例子,改变hash值并不会导致浏览器向服务器发送请求,
浏览器不发出请求,也就不会刷新页面,
hash 值改变,触发全局 window 对象上的 hashchange 事件
hash 模式路由是利用 hashchange 事件监听 URL 的变化,
从而进行 DOM 操作来模拟页面跳转

65.SPA首屏加载速度慢的怎么解决?

减小入口文件体积
静态资源本地存储
UI框架按需加载
图片资源的压缩
组件重复打包
开启Gzip压缩
使用SSR

66.什么是响应式设计?响应式设计的基本原理是什么?如何做?

响应式设计也叫响应式布局,响应式开发
实现不同屏幕分辨率的终端上浏览网页的不同展示方式
响应式布局是根据设备屏幕宽度不同适当调整标签显示的布局
从而在每种设备屏幕宽度下呈现的界面是不同的
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理

67.说说你对keep-alive的理解?

keep-alive是vue中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM
keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
keep-alive可以设置的props属性:
include:字符串或正则表达式,只有名称匹配的组件会被缓存
exclude:字符串或正则表达式,任何名称匹配的组件都不会被缓存
max:数字,最多可以缓存多少组件实例

68.VUE路由的原理?

本质是监听url的变化,然后匹配路由规则,
显示相应的页面,并且不刷新页面
目前单页面应用实现路由的方式有两种:
hash模式和history模式
hash模式相当于瞄点跳转,监听url#后面的传值发生变化,
从而触发window.hashchange方法,并根据值修改暂时页面的内容,不会刷新页面history模式相对hash模式更加符合常见的url格式,原理是触发原生的window.history方法

69.怎么理解回流跟重绘?什么场景下会触发?

重绘

就是重新绘画,当给一个元素更换颜色、更换背景,虽然不会影响 页面布局 ,但是颜色或背景变了,就会重新渲染页面,这就是重绘
重绘不会引起dom结构和页面布局的变化,只是样式的变化,有重绘不一定有回流

回流:

当增加或删除dom节点,或者给元素修改宽高时,会改变页面布局,
那么就会重新构造dom树然后再次进行渲染,这就是回流
回流则是会引起dom结构和页面布局的变化,有回流就一定有重绘,都是会影响性能

回流触发时机

添加或删除可见的DOM元素
元素的位置发生变化
元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
页面一开始渲染的时候
浏览器的窗口尺寸变化

重绘触发时机

触发回流一定会触发重绘
颜色的修改
文本方向的修改
阴影的修改

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值