面试题
- React
- 1.props和state相同点和不同点?render方法在哪些情况下会执行?
- 2.说说你对Object.defineProperty()的理解?
- 3.说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?
- 4.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?
- 5.React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?
- 6.React组件之间如何通信?
- 7.ts中抽象类的理解?
- 8.redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?
- 9.redux中同步action与异步action最大的区别是什么?
- 10.redux-saga和redux-thunk的区别与使用场景?
- 11.在使用redux过程中,如何防止定义的action-type的常量重复?
- 12.CDN的特点及意义?
- 13.为什么for循环比forEach性能高?
- 14.redux实现原理?
- 15.React render方法的原理,在什么时候会触发?
- 16.找出数组【1,2,3,4,5,3,2,2,4,2,2,3,1,3,5】中出现次数最多的数,并统计出现多 少次,编写一个函数?
- 17.什么是闭包,应用场景是什么?
- 18.谈谈你是如何做移动端适配的?
- 19.移动端1像素的解决方案?
- 20.弹性盒中的缩放机制是怎样的?
React
1.props和state相同点和不同点?render方法在哪些情况下会执行?
不同点:Props(属性)是从父组件传递给子组件的,组件内部无法直接修改 值。Props是只读的。
用于存储组件外部的数据,应该被视为不可变的。
是由父组件传递下来的,遵循单向数据流的原则。
State(状态)是组件内部管理的数据,可以通过setState()方法进行修改。State是可变的。
用于存储组件内部的状态数据,可以在组件内部进行修改。
通常用于存储用户输入、组件特定的数据或需要在组件内部更新的数据。
相同点:都用于存储和管理组件中的数据
都可以用于将数据从父组件传递给子组件
当Props或State发生变化时,都可以触发组件的重新渲染
Props和State都可以在组件的render方法中访问,并用于渲染动态内容
Render执行:
组件首次挂载到DOM时会调用render方法进行初始渲染。当组件的props或state发生变化时,会触发组件的重新渲染,即再次调用render方法。
当父组件重新渲染时,子组件也会重新渲染,即调用子组件的render方法
2.说说你对Object.defineProperty()的理解?
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
该方法接受三个参数
第一个参数是 obj:要定义属性的对象,
第二个参数是 prop:要定义或修改的属性的名称或 Symbol,
第三个参数是 descriptor:要定义或修改的属性描述符
函数的第三个参数 descriptor 所表示的属性描述符有两种形式:数据描述符和存取描述符。
数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。
存取描述符由 getter函数和 setter 函数所描述的属性。
一个描述符只能是这两者其中之一;不能同时是两者。
这两种同时拥有下列两种键值:
configurable:是否可以删除目标属性或是否可以再次修改属性的特性。设置为true可以被删除或可以重新设置特性;设置为false,不能被可以被删除或不可以重新设置特性。默认为false。
enumerable: 当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。默认为 false。
3.说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?
1、实际上它只是一层对真实DOM的抽象,以JavaScript对象(VNode节点)作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作时这棵树映射到真实环境上,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
2、通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进行一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。
在虚拟dom计算的时候diff和key之间有什么关系:
1、React需要同时维护两棵虚拟DOM树:一棵表示当前的DOM结构,另一棵在React状态变更将要重新渲染时生成。React通过比较这两棵树的差异,决定是否需要修改DOM结构,以及如何修改。这种算法称作Diff算法。
2、key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率。
4.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?
React新增的两个生命周期钩子函数?
1、getDerviedStateFromProps
作用:从props中获取衍生的state
2、getSnapshotBeforeUpdate
作用:在组件更新前获取快照,一般结合componentDidUpdate使用,getSnapBeforeUpdate中返回值将作为第三参数传递给componentDidUpdate
它和componentDidUpdate将render夹在中间,其实它的核心作用就是在render改变dom之前,记录更新前的dom信息传递给componentDidUpdate。
二、React新的生命周期去除的钩子函数?
1、componentWillMount
2、componentWillReceiveProps
3、componentWillUpdate
总结
1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。
2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替;
3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替
5.React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?
使用react.Children.map:遍历props.children
将props.children转换为数组:使用Array.from或展开运算符[…]
6.React组件之间如何通信?
1、父组件向子组件传递信息:由于react数据流动是单向的,父组件在调用子组件时,只需要在子组件标签内传递参数,子组件通过props属性接收
2、子组件向父组件传递信息;父组件向子组件传递一个函数,然后通过这个函数的回调,拿到子组件传过来的值
3、兄弟组件之间的传递:父组件作为中间层来实现数据的互通,通过使用父组件传递
4、父组件向后代组件传值:使用context提供的组件通信的一种方式,可以实现数据的共享,Provider组件通过value属性传递给后代组件
5、非关系组件传递数据:将数据进行一个全局的资源管理,从而实现组件间的通信功能,例如redux
7.ts中抽象类的理解?
在 TypeScript 中,抽象类是用于定义标准或基类的概念,它不允许被实例化。抽象类的主要作用有:
定义标准接口:抽象类可以定义标准接口,子类必须实现抽象类中的所有方法和属性。
代码复用:抽象类可以包含部分通用代码,子类通过继承实现共享代码。
类型检查:TypeScript 编译器会检查子类是否正确实现了抽象类中的所有抽象方法和属性
8.redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?
Redux本身是一个状态的同步管理库,通过中间件来执行异步代码。允许在派发和到达reducer之间的过程中拦截和处理额外逻辑
中间件实现原理:基于redux的洋葱模型或管道模型。当一个action被派发,会经过中间件,通过next函数传递给下一个中间件,直到达到最后一个中间件。每个中间件都可以对action进行处理,处理完后,action进行状态更新
中间件可以在派发action和到达reducer之间执行一些异步操作,如发起网络请求,处理副作用,触发其他action
常见的中间件:redux-thunk redux-saga
9.redux中同步action与异步action最大的区别是什么?
同步action是一个简单的对象,描述了发生审美类型的事件。并携带一些数据,会直接执行action,不涉及任何异步操作
异步的action是一个函数。异步action会执行一些异步操作,比如网络请求等,会通过redux中的store管理状态,通过redux的store进行派发,然后执行异步action操作
10.redux-saga和redux-thunk的区别与使用场景?
区别:
实现方式:redux-saga使用es6的Generator函数处理异步操作。创建一个单独的线程,在该线程中监听redux的action,以声明式的方式处理异步操作。
redux-thunk是一个函数,允许在redux中派发函数类型的action,不仅仅是一个简单的对象。派发一个函数类型的action时,redux-thunk会拦截action,执行该函数,可以在函数中执行异步操作,完成后派发一个同步的action来更新状态
复杂度和灵活性:redux-thunk相对简单,适用于处理相对简单的异步操作,网络请求或延迟操作。redux-saga提供了更高级的抽象,用于处理复杂的异步流程和副作用。可以处理各种异步操作
使用场景:redux-thunk适用于简单的异步操作,发起简单的网络请求、处理表单提交等 redux-saga处理更复杂的异步操作加粗样式等,比如处理webSocket等
11.在使用redux过程中,如何防止定义的action-type的常量重复?
统一管理:将所有的action-type的常量,进行统一管理,创建一个单独的文件或模块,定义和导出所有的action-type的常量,避免action-type的常量重复
命名空间:使用命名空间,来防止action-type的常量重复
唯一性检查:可以编写脚本或工具检查,确保没有重复定义,检查常量的唯一性,给出警告或错误提示。
使用工具库:使用一些工具库来帮助管理和防止常量重复。例如redux-actions来自动生成action-type的常量,根据action名称生成唯一常量
12.CDN的特点及意义?
CDN是一个分布式的网络架构,用于提供高效的内容分发服务
特点:
分布式:CDN采用分布式的服务器网络,将内容分发到离用户更近的边缘节点,减少网络延迟和提高访问速度
缓存机制:CDN通过在边缘节点缓存静态内容,减轻源服务器的负载,提高响应速度
高可用性:具有高可用性,即使某个节点发生故障,其他节点仍然可以继续提供服务。
负载均衡:根据用户的位置和网络状况,智能的选择最有节点提供服务,实现负载均衡
意义:提高用户访问速度 减轻源服务器负载 改善网络传输效率
提供高可用性和可靠性 降低网络成本
13.为什么for循环比forEach性能高?
作用域链访问:for循环中的变量直接在当前作用域访问,foreach方法中的回调函数会在一个新的作用域中执行。Foreach中访问外部变量时,需要通过作用域链查找,导致性能上的开销
优化机制:for循环是一种基本的循环结构,js在执行for循环时可以进行更多的优化和内联操作,forEach是一个高阶函数,在进行循环的时候需要遍历数组并针对每个元素执行回调函数,导致额外的函数调用和迭代开销
可中断性:for循环可以通过break语句或return语句终止循环。Foreach无法直接中断循环
14.redux实现原理?
Redux是将整个应用状态存储在一个公共的store文件中,组件可以派发(dispatch)行为(action)给公共store,
而不是直接通知其他组件,组件内部通过订阅store中的状态state来刷新自己的视图
首先创建store:使用redux提供的createStore方法创建一个store对象,
接下来创建reducer: reducer不具备任何功能,创建store时必须要有一个reducer
在页面中引入store文件通过store.getState()来获取
通过store的dispatch方法发出一个action用于修改值,可以理解为告诉redux我们准备做的事)
在reducer中接收发出的值,通过return 返还最新的值redux接收到新的state对象后,通知store.subscribe0函数执行
执行流程:组件=>action=>reducer=>store=>组件
15.React render方法的原理,在什么时候会触发?
原理:
首次渲染:当组件被挂载到DOM时,react会调用组件的render方法,获取组件的输出内容。Render方法返回一个react元素,描述了组件应该如何在dom中呈现。
数据更新:当组件的props或state发生变化时,react会重新调用组件的rener方法,获取组件新的输出内容,react通过比较前一次渲染的输出和当前输出,找出差异更新dom,实现局部更新,而不是重新渲染
虚拟dom比较:使用虚拟dom进行比较,通过新旧dom树比较,找出差异,并更新
触发:组件的props或state发生变化,当组件的props或state发生变化,会重新调用render方法,获取新的输出内容,并惊醒dom更新
16.找出数组【1,2,3,4,5,3,2,2,4,2,2,3,1,3,5】中出现次数最多的数,并统计出现多 少次,编写一个函数?
function findMostFrequentNumber(arr) {
const countMap = {};
arr.forEach(num => {
if (countMap[num]) {
countMap[num]++;
} else {
countMap[num] = 1;
}
});
let mostFrequentNumber;
let maxCount = 0;
for (const num in countMap) {
if (countMap[num] > maxCount) {
mostFrequentNumber = parseInt(num);
maxCount = countMap[num];
}
}
// 返回结果
return {
number: mostFrequentNumber,
count: maxCount
};
}
17.什么是闭包,应用场景是什么?
闭包是指在一个内部函数中访问外部函数作用域的能力。闭包就是能够记住并访问定义时的词法环境的函数
优点:数据封装:闭包可以将变量和函数封装在内部函数中,隐藏实现细节,只暴露需要的接口。
保持状态:可以保持函数执行时的状态,可以在函数执行完毕后继续访问和使用
实现函数工厂:可以动态生成函数,根据不同的参数生成不同的函数
缺点:内存消耗:不被正确释放,导致内存消耗
性能影响:作用域链比普通函数长,访问外部变量速度慢,影响函数执行效率
可读和可维护性:过多或复杂的闭包嵌套导致代码难以理解,维护和调试
应用场景:
保持状态和数据的私有性:闭包可以用于创建私有变量和函数,保持数据的安全性
事件处理函数:可以用于在事件处理程序中保持状态和访问外部变量
模块化开发:闭包可以用于进行模块化开发,将变量和函数封装在私有作用域中,只暴露需要的接口。
延迟函数执行:可以用于延迟函数执行,保存函数的状态和参数,在需要时执行函数
18.谈谈你是如何做移动端适配的?
使用响应式布局:使用css的媒体查询来适配不同的设备和屏幕尺寸
使用viewprot单位:
弹性布局:使用Flex或Gird
图片适配:使用响应式图片或css的max-width属性确保图片在不同尺寸下适应
使用移动端优化的css框架
19.移动端1像素的解决方案?
使用css的border属性
使用伪元素和缩放
使用特定的css库或工具
使用svg或ICON Font
20.弹性盒中的缩放机制是怎样的?
弹性盒子布局是一种用于创建灵活的、自适应的页面css布局模型。在弹性盒子中,弹性缩放机制用于控制弹性盒子内项目的的缩小行为
在弹性盒子中,每个项目都有flex-shrink属性,用于确定项目在空间不足时是否要缩小以及缩小的比例。flex-shrink属性接收一个非负整数,默认值为1
本文详细阐述了React中的props和state区别,虚拟DOM的工作原理,React新钩子函数及其与旧生命周期的区别,Redux的异步操作、中间件和action类型管理,以及移动端适配和性能优化等内容。
1685

被折叠的 条评论
为什么被折叠?



