面试题(持续更新中)

一、props和state相同点和不同点render方法在哪些情况下会执行?

相同点:

  1. 都是用来存储组件的数据。
  2. 当数据发生变化时,都会触发组件重新渲染。

不同点:

  1. props是由父组件传递给子组件的,而state是组件自身管理的。
  2. props是只读的,而state可以被组件自身修改。
  3. props通常用于传递不变的数据,而state通常用于存储可变的数据。

render方法在以下情况下会执行:

  1. 组件初始化渲染时,会执行一次render方法。
  2. 当组件的props或state发生变化时,会触发重新渲染,执行render方法。
  3. 当父组件重新渲染时,子组件也会重新渲染,执行render方法。
  4. 当调用forceUpdate方法时,会强制组件重新渲染,执行render方法

二、shouldComponentUpdate有什么作用?

shouldComponentUpdate是React组件生命周期方法之一,它用于控制组件是否需要重新渲染。

shouldComponentUpdate的作用是优化组件性能。

默认情况下,每当组件的props或state发生变化时,React会重新渲染组件。但是,在某些情况下,组件的props或state的变化可能并不会影响到组件的渲染结果,这时可以通过shouldComponentUpdate方法来判断是否需要进行重新渲染。

shouldComponentUpdate方法接收两个参数:nextProps和nextState,表示组件即将接收到的新props和新state。在shouldComponentUpdate方法中,可以根据新的props和state与当前的props和state进行比较,返回一个布尔值来决定是否需要重新渲染组件。

如果shouldComponentUpdate返回false,React将不会继续执行后续的生命周期方法和重新渲染组件,从而提高组件的性能。如果shouldComponentUpdate返回true,React将继续执行后续的生命周期方法和重新渲染组件。

通过实现shouldComponentUpdate方法,可以避免不必要的组件渲染,提高应用的性能。但是需要注意,过度使用shouldComponentUpdate可能会导致组件渲染不及时,因此在实现shouldComponentUpdate时需要权衡性能和渲染准确性。

三、说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关

在React中,虚拟DOM(Virtual DOM)是一种用JavaScript对象表示真实DOM的轻量级副本。它是React用来提高性能和渲染效率的一种机制。

虚拟DOM的工作原理是,当组件的状态发生变化时,React会创建一个新的虚拟DOM树,并与之前的虚拟DOM树进行比较。通过比较两棵虚拟DOM树的差异,React可以找出需要更新的部分,并将这些差异应用到真实DOM上,以实现局部更新,而不是重新渲染整个页面。

在虚拟DOM计算的过程中,diff算法和key起着重要的作用。

diff算法是用来比较两棵虚拟DOM树的差异的算法。它会逐层比较虚拟DOM树的节点,并找出需要更新的节点。React使用了一种高效的diff算法,可以在最优化的时间复杂度下找到最小的差异。

key是React要求在进行列表渲染时,每个列表项都要有一个唯一的标识符。在虚拟DOM计算的过程中,key的作用是帮助React识别列表项的变化。通过比较新旧虚拟DOM树中的key,React可以判断哪些列表项是新增的、删除的或移动的,从而减少不必要的DOM操作,提高性能。

因此,diff算法和key是密切相关的。key可以帮助diff算法更准确地找出需要更新的节点,从而减少不必要的渲染和操作。使用正确的key可以提高React应用的性能和渲染效率。

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

React类组件新出来的两个钩子函数是getDerivedStateFromPropsgetSnapShotBeforeUpdate

  1. getDerivedStateFromProps:这个钩子函数在组件接收到新的props时被调用,它接收两个参数:propsstate,并返回一个对象来更新state,或者返回null表示不需要更新state。它用于替代componentWillReceiveProps钩子函数,用于根据props的变化来更新state。

  2. getSnapShotBeforeUpdate:这个钩子函数在组件即将更新(重新渲染)到DOM之前被调用,它接收两个参数:prevPropsprevState,并返回一个值(snapshot)作为后续componentDidUpdate钩子函数的第三个参数。它用于替代componentWillUpdate钩子函数,用于在更新之前获取DOM的快照或执行其他操作。

区别:

  1. 生命周期钩子函数(如componentWillReceivePropscomponentWillUpdate)是在组件的生命周期中被调用的,而新的钩子函数(如getDerivedStateFromPropsgetSnapshotBeforeUpdate)是静态方法,不依赖于组件实例。

  2. 生命周期钩子函数可以在组件挂载、更新和卸载时执行相应的操作,而新的钩子函数只关注组件的props和state的变化,并在特定的时机执行相应的操作。

  3. 生命周期钩子函数的执行是同步的,而新的钩子函数的执行是在更新过程中的特定时机被调用,可能是异步的。

总的来说,新的钩子函数提供了更精确和可控的方式来处理组件props和state的变化,并且更符合React的设计思想。同时,新的钩子函数也更易于理解和使用。

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

在react中props.children不一定是数组

有三种可能:

1.当前组件没有子节点,数据类型就是undefined

2.有一个子节点,数据类型是object

3.有多个子节点的时候才会是array,只有在多个节点的时候可以直接调用map方法,

react自身提供了一个React.childen.map()方法可以安全遍历节点对象。

六、谈谈你对immutable.js的理解?

Immutable.js是一个用于处理不可变数据的JavaScript库。他提供了一组不可变数据结构,如List、Map、Set等这些数据结构被创建后是不可变的,既不能被修改。当对不可变数据结构进行操作时,会返回一个新的不可变数据,而不是修改原始数据。

Immutable.js的主要优势在于它可以帮助我们处理复杂的数据操作,同时提供了性能优化。

由于不可变数据的特性,我们可以通过比较引用来判断数据是否发生变化,从而避免深层次的逐个字段比较。这样可以提高比较的效率,并且减少不必要的渲染

总的来说,Immutable.js是一个强大的库,可以帮助我们更好地管理和操作不可变数据。它在React等前端框架中被广泛应用,可以提高应用的性能和可维护性。

七、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么

Redux本身是一个同步的状态管理库,但是它提供了一种机制来处理异步操作,这个机制就是中间件。

中间件是一种位于action被发起之后,到达reducer之前的处理函数。它可以拦截、处理和转发action,从而实现异步操作。

Redux中间件的实现原理是基于函数的柯里化(currying)和函数组合(compose)的概念。它通过对多个中间件函数进行组合,形成一个中间件链,每个中间件函数都可以对action进行处理,并将处理后的action传递给下一个中间件函数或者最终的reducer。

当使用中间件时,Redux会将中间件链与store进行绑定,当一个action被dispatch时,它会按照中间件链的顺序依次经过每个中间件函数的处理,直到最后一个中间件函数将处理后的action传递给reducer进行状态更新。

中间件的实现原理可以简单概括为以下几个步骤:
1. 创建中间件函数,该函数接收store的dispatch和getState方法作为参数,返回一个函数,即中间件函数的next参数。
2. 在中间件函数中,可以对action进行处理,然后调用next方法将处理后的action传递给下一个中间件函数或者reducer。
3. 将多个中间件函数通过compose函数进行组合,形成中间件链。
4. 使用createStore方法创建store时,将中间件链作为参数传递给applyMiddleware函数,将中间件链与store进行绑定。
5. 当一个action被dispatch时,它会按照中间件链的顺序依次经过每个中间件函数的处理,直到最后一个中间件函数将处理后的action传递给reducer进行状态更新。

通过中间件的实现原理,Redux能够处理异步操作,比如发送网络请求、处理定时器等,从而增强了Redux的功能和灵活性。

八、redux-saga和redux-thunk的区别与使用场景?

Redux-saga和Redux-thunk是两种常用的Redux中间件,用于处理异步操作和副作用。

区别:

Redux-thunk是一个简单的中间件,它允许action创建函数返回一个函数,而不是一个普通的action对象。这个返回的函数可以在内部进行异步操作,并且可以在异步操作完成后再派发一个真正的action。它的工作原理是Redux的dispatch过程中,检查action是否是一个函数,如果是就执行这个函数,并将dispatch函数和getState函数作为参数传递给它。这种方式使得我们可以在action创建函数中进行异步操作,例如发送网络请求或定时器等。

Redux-saga是一个强大的Redux中间件,它使用了ES6的Generator函数来处理异步操作和副作用。它通过创建一个叫做saga的Generator函数,来监听Redux的action,并在满足特定条件时执行相应的副作用。saga函数可以通过使用一些特定的effect来处理异步操作,例如调用API、延迟、并发等。它的工作原理是通过创建一个后台运行的saga任务来监听Redux的action,并在满足特定条件时执行相应的副作用。

九、CDN的特点及意义?

cdn是分布式服务器网络,用于提供高效的内容分发服务

特点:

     1..高速传输:CDN通过在全球各地建立分布式节点服务器,将内容缓存到离用户最近的节点上。当用户请求内容时,CDN会将内容从最近的节点传输给用户,减少了传输距离和网络延迟,提高了传输速度。

2.负载均衡:CDN可以根据用户的地理位置和网络状况,将用户的请求分发到最合适的节点服务器上。这样可以避免单个服务器负载过高,提高了系统的稳定性和可靠性。

3.提高网站性能:由于CDN可以将内容缓存在离用户最近的节点上,用户再次请求相同的内容时,可以直接从缓存中获取,减少了对源服务器的请求,提高了网站的响应速度和性能。

4.减轻源服务器压力:CDN可以将用户请求的内容分发到不同的节点服务器上,减少了对源服务器的直接请求,降低了源服务器的负载压力,提高了网站的可扩展性和可靠性。

5.提供安全性:CDN可以通过一些安全机制,例如SSL加密和防御DDoS攻击等,保护网站的内容和用户的隐私安全。

6.降低成本:由于CDN可以提供高效的内容分发服务,可以减少对带宽和服务器的需求,降低了网站运营的成本。

CDN通过分布式网络和缓存技术,提供了高速传输、负载均衡、提高网站性能、减轻源服务器压力、提供安全性和降低成本等优势

十、为什么for循环比forEach性能高?

  1. 遍历速度:for循环的遍历速度通常比forEach快。这是因为for循环直接使用索引进行迭代,而forEach需要在每次迭代时调用一个回调函数。因此,在大规模迭代时,for循环可以更快地完成遍历。

  2. 适用性:for循环在处理简单的迭代任务时更加灵活。它可以用于遍历数组、对象和其他可迭代的数据结构,并且可以根据需要自定义迭代逻辑。与之相反,forEach只能用于遍历数组,并且不能中途中断或跳出循环。

  3. 内存占用:forEach使用了回调函数,这意味着它会创建一个新的函数作用域,并且在每次迭代时都会将该函数推入调用栈。这可能会导致额外的内存开销。相比之下,for循环没有这个额外的开销,因为它直接在当前作用域中执行迭代逻辑。

性能差异可能在实际应用中并不明显,并且在某些情况下,forEach可能更易于阅读和编写。因此,在选择使用for循环还是forEach时,应该根据具体情况进行权衡,并考虑代码的可读性和维护性。

十一、谈谈你是如何做移动端适配的?

  1. 响应式设计:使用CSS媒体查询和弹性布局等技术,根据设备的屏幕尺寸和分辨率动态调整网页的布局和样式。这样可以确保网页在不同设备上都能自适应地展示,并提供良好的用户体验。

  2. 弹性单位使用相对单位(如百分比、em、rem)来设置元素的尺寸和间距,而不是使用固定的像素值。这样可以根据设备的屏幕尺寸和分辨率进行自适应调整,使元素在不同设备上保持一致的相对大小。

  3. 图片适配:使用CSS的max-width属性或媒体查询,控制图片在不同设备上的大小和显示方式。可以根据设备的屏幕宽度选择合适的图片尺寸,避免加载过大的图片,提高页面加载速度

十二、弹性盒中的缩放机制是怎样的?

弹性盒(Flexbox)是一种用于布局的CSS模块,它提供了一种灵活的方式来创建响应式的布局。在弹性盒中,可以通过设置flex属性来控制元素的缩放机制。

  1. Flex-grow(放大):通过设置flex-grow属性,可以指定元素在可用空间增加时的放大比例。默认值为0,表示元素不会放大。如果所有的元素都设置了相同的flex-grow值,它们会等比例地放大以填充可用空间。如果某个元素的flex-grow值大于其他元素,它会相对于其他元素放大更多。

  2. Flex-shrink(缩小):通过设置flex-shrink属性,可以指定元素在可用空间减少时的缩小比例。默认值为1,表示元素会按照其宽度的比例缩小以适应可用空间的减少。如果某个元素的flex-shrink值为0,它不会缩小,而其他元素会相对于它缩小。

  3. 在弹性盒中,还可以使用flex-basis属性来指定元素的基准尺寸,即元素在没有放大或缩小时的初始尺寸。可以使用像素值、百分比或关键字(如auto)来设置flex-basis。

十三、移动端1像素的解决方案?

  1. 使用CSS的transform缩放:可以使用CSS的transform属性对元素进行缩放,将1像素的线条放大到设备像素的大小。例如,可以将一个1像素的边框线条缩放为0.5倍,达到显示细线的效果。
    .box {
      border: 1px solid #000;
      transform: scaleY(0.5);
    }
  2. 使用CSS的伪元素和background渐变:可以通过伪元素和CSS的background渐变来创建1像素的线条。将伪元素的高度设为1像素,然后使用background渐变来模拟1像素的线条。
    .box::before {
      content: "";
      display: block;
      height: 1px;
      background: linear-gradient(to right, #000 0%, #000 50%, transparent 50%, transparent 100%);
    }
  3. 使用图片(不建议使用)

  4. 使用CSS的box-shadow:可以使用CSS的box-shadow属性来创建1像素的阴影,从而模拟1像素的线条

    .box {
      box-shadow: 0 1px 0 0 #000;
    }

十四、(待)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值