目录
10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
15.React render方法的原理,在什么时候会触发?
18. Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?
19.说说你对Object.defineProperty()的理解?
1.说说React生命周期中有哪些坑?如何避免?
在代码编写中,遇到的坑往往会有两种:
在不恰当的时机调用了不合适的代码;
在需要调用时,却忘记了调用。
通过梳理生命周期,明确周期函数职责,确认什么时候该做什么事儿,以此来避免坑。
getDerivedStateFromProps 容易编写反模式代码,使受控组件与非受控组件区分模糊。
shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。
如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。
如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加。
2.说说React diff算法是怎么运作的?
diff算法可以看作是一种对比算法,对比的对象是新旧虚拟Dom。顾名思义,diff算法可以找到新旧虚拟Dom之间的差异,但diff算法中其实并不是只有对比虚拟Dom,还有根据对比后的结果更新真实Dom。
合理利用
key
可以有效减少真实Dom的变动,从而减少页面重绘和回流的频率,进而提高页面更新的效率。
3.调和阶段setState干了什么?
setState是异步还是同步:
合成事件中是异步
钩子函数中的是异步
原生事件中是同步
setTimeout中是同步1)代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
(2)经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
(3)在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
(4)在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
4.说说redux的实现原理是什么?
1.将应用的状态统一放到state中,由store来管理state。
2.reducer的作用是返回一个新的state去更新store中对用的state。
3.按redux的原则,UI层每一次状态的改变都应通过action去触发,action传入对应的reducer 中,reducer返回一个新的state更新store中存放的state,这样就完成了一次状态的更新
4.subscribe是为store订阅监听函数,这些订阅后的监听函数是在每一次dipatch发起后依次执行
5.可以添加中间件对提交的dispatch进行重写
5.React合成事件的原理?
react自身实现了一套事件机制,包括事件的注册、事件的存储、事件的合成及执行等。
react 的所有事件并没有绑定到具体的dom节点上而是绑定在了document 上,然后由统一的事件处理程序来派发执行。
通过这种处理,减少了事件注册的次数,另外react还在事件合成过程中,对不同浏览器的事件进行了封装处理,抹平浏览器之间的事件差异。
react会根据原生事件类型来使用不同的合成事件对象,比如: 聚焦合成事件对象SyntheticFoucsEvent
(合成事件对象:SyntheticEvent
是react合成事件的基类,定义了合成事件的基础公共属性和方法。合成事件对象就是在该基类上创建的)
6.React组件之间如何通信?
- 使用发布与订阅,publish
- 使用redux
- 将数据绑定在组件实例上,通过props传递
- 将数据存放在本地存储中
- 通过路由跳转的方式传值
7.为什么react元素有一个$$type属性?
8.说说Connect组件的原理是什么?
let store = createStore(reducer); // 创建store
store.getState( ); // 获取state值
store.dispatch({ type: "text" }); // 使用action更改在reducer中定义好的更改store的更改策略
store.subScribe(render); // 设置监听函数, 在更改store之后触发connect 的第一个参数是 mapStateToProps
这个函数允许我们将 store 中的数据作为 props 绑定到组件上
connect 的第二个参数是 mapDispatchToProps
由于更改数据必须要触发
action
, 因此在这里的主要功能是将action
作为props
绑定到 组件上Provider就是react-redux中的一个组件, Provider 做的事情也简单, 它就是一个容器组件, 会把嵌套的内容原封不动作为自己的子组件渲染出来. 它还会把外界传给它的 props.store 放到 context, 这样子组件 connect 的时候都可以获取到.
9.说说你对fiber架构的理解?解决了什么问题?
什么是fiber:react16以后的一个虚拟dom思想
为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务
增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行
dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行
10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
中间件:它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的
常用的中间件
有很多优秀的
redux
中间件,这里我们例举两个:
redux-thunk:用于异步操作
redux-logger:用于日志记录
上述的中间件都需要通过
applyMiddlewares
进行注册,作用是将所有的中间件组成一个数组,依次执行然后作为第二个参数传入到createStore
中redux-thunk中间件会判断你当前传进来的数据类型,如果是一个函数,将会给函数传入参数值(dispatch,getState)
- dispatch函数用于我们之后再次派发action
- getState函数考虑到我们之后的一些操作需要依赖原来的状态,用于让我们可以获取之前的一些状态
11.React性能优化的手段有哪些?
1、使用纯组件;
2、使用 React.memo 进行组件记忆(React.memo 是一个高阶组件),对 于相同的输入,不重复执行;
3、如果是类组件,使用 shouldComponentUpdate(这是在重新渲染组件之前触发的其中一个生命周期事件)生命周期事件,可以利用此事件来决定何时需要重新渲染组件;
4、路由懒加载;
5、使用 React Fragments 避免额外标记;
6、不要使用内联函数定义(如果我们使用内联函数,则每次调用“render”函数时都会创建一个新的函数实例);
7、避免在Willxxx系列的生命周期中进行异步请求,操作dom等;
8、如果是类组件,事件函数在Constructor中绑定bind改变this指向;
9、避免使用内联样式属性;
10、优化 React 中的条件渲染;
11、不要在 render 方法中导出数据;
12、列表渲染的时候加key;
13、在函数组件中使用useCallback和useMemo来进行组件优化,依赖没有变化的话,不重复执行;
14、类组件中使用immutable对象;
12.说说你对事件循环event loop的理解?
事件循环分为两种,分别是浏览器事件循环和node.js事件循环,本文主要对浏览器事件循环进行描述。
我们都知道JavaScript是一门单线程语言,指主线程只有一个。Event Loop事件循环,其实就是JS引擎管理事件执行的一个流程,具体由运行环境确定。目前JS的主要运行环境有两个,浏览器和Node.js。
13.前端跨域的解决方案?
1.JSONP跨域
2.cors
3.nginx代理跨域
4.postMessage跨域
5.WebSocket协议跨域
14.数组常用方法及作用,至少15个?
Filter、map、foreach、some、erray、find、indexof、splice、slice、concat、fill、filler、findIndex、join
15.React render方法的原理,在什么时候会触发?
一、原理
在类组件和函数组件中,render函数的形式是不同的。
在类组件中render函数指的就是
render
方法;而在函数组件中,指的就是整个函数组件。二、触发时机
render
的执行时机主要分成了两部分:类组件调用 setState 修改状态
函数组件通过
useState hook
修改状态
16.说说你对vue中mixin的理解?
Mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类
当一段代码非常相似的时候就可以抽离成一个mixin
mixins是一个js对象,它可以包含我们组件中script项中的任意功能选项,如data、components、methods 、created、computed等等。我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来,这样就可以提高代码的重用性,使你的代码保持干净和易于维护。
17. for...in循环和for...of循环的区别?
for...in
和for...of
都是JavaScript
中遍历数据的方法
for...in
是为遍历对象属性而构建的,它以任意顺序遍历一个对象的除Symbol
以外的可枚举属性,可用break
或者throw
跳出
for...of
语句在可迭代对象上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句(包括Array
,Map
,Set
,String
,TypedArray
,arguments
等等,不包括Object
),可用break
或者throw
跳出。
18. Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?
typeof:
可以判断数据类型,它返回表示数据类型的字符串(返回结果只能包括number,boolean,string,function,object,undefined);
可以使用typeof判断变量是否存在
instanceof:
一般用来检测引用数据类型,表达式为:A instanceof B,判断A是否是B的实例,如果 A 是 B 的实例,则返回 true,否则返回 false,由构造类型判断出数据类型
constructor:
constructor是prototype对象上的属性,指向构造函数,
Object.prototype.toString.call():
用来检测对象类型
jquery.type()
19.说说你对Object.defineProperty()的理解?
Object.defineProperty()方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象
value:设置属性的值
writable:值是否可以重写。 true|false
enumerable: 目标属性是否考可以被枚举。 true | false
configurable: 目标属性是否可以被删除或是可以在此修改特性 true|false
set:目标属性设置值的方法
get:目标属性获取值的方法
20.说说你对webSocket的理解?
webSocket是html5提供的与浏览器与服务器进行网络交互,他的特点就是服务器可以向客户端传递消息,客户端也可以向服务器发送消息