2024最新最全的React面试题

1.react和vue的区别?
(1)设计理念:
React: 更倾向于函数式编程思想,推崇组件的不可变性和单向数据流。
Vue: 结合了响应式编程和模板系统,致力于简化开发过程。
(2)核心库与生态系统:
React: React本身只关注UI层,但它有一个庞大的生态系统,例如Redux、MobX等用于状态管理,以及React Router用于路由处理。
Vue: Vue是一个更完整的解决方案,它的核心库除了视图层,还内置了例如Vuex(状态管理)和Vue Router(路由管理)等解决方案。
(2)模板语法:
React: 使用JSX(JavaScript XML),将标记语言与JavaScript逻辑混写。
Vue: 使用基于HTML的模板语法,允许开发者使用纯HTML、CSS和JavaScript。
(3)数据绑定:
React: 主要采用单向数据流,组件状态通过setState方法更新。
Vue: 支持双向数据绑定(使用v-model指令),适合于简化表单输入等场景。
(4)组件化:
React与Vue: 都支持基于组件的架构,但在定义组件方式上有所不同。React推崇函数式组件和Hooks,Vue则提供了一个选项式API。
(5)状态管理:
React: 状态管理通常通过使用Context API或引入如Redux、MobX的库来实现。
Vue: Vue提供了Vuex作为官方的状态管理解决方案。
(6)响应式系统:
React: 通过setState和useState等API显式地触发UI更新。
Vue: 通过其响应式系统自动追踪依赖并在数据变化时更新视图。
(7)类型支持:
React: 原生支持JavaScript,但可以很好地与TypeScript结合。
Vue: Vue 3提供了更好的TypeScript支持。

2.React类式组件和函数式组件的区别有哪些呢?
(1)语法不同、设计思想不同
函数式组件是函数式编程思想,而类组件是面向对象编程思想。面向对象编程将属性和方法封装起来,屏蔽很多细节,不利于测试。
(2)生命周期、状态变量
类式组件:使用state对象定义状态变量,有诸如componmentDidMount、shouldComponentUpdate等生命周期钩子函数;
函数式组件:没有this,使用一系列的内置hooks实现对应的功能,比如使用useState创建状态变量,使用useEffect实现类似于componmentDidMount、shouldComponentUpdate等生命周期钩子函数的功能。
(3)复用性
类式组件:使用hoc(高阶组件)、render props实现组件的逻辑复用、拓展组件的功能。
函数式组件:使用自定义hooks实现组件的逻辑复用。
(4)优缺点
函数式组件优点:
相对于类式组件,一般情况而言,代码量更少,代码更简洁,可读性更强;
更易于拆分组件和测试;
缺点:
在业务逻辑巨复杂,状态依赖关系错乱的情况下,使用useEffect、useMemo等hooks,对其依赖项数组的思考为开发者带来了更大的心智负担;
不具备处理错误边界等业务情况的hooks;
类式组件优点:
功能完备,具有componentDidsCatch、getDerivedStateFromError等钩子函数处理边界错误;
缺点:
在复用性上,hoc组件等会出现诸如嵌套地狱、重名props被覆盖、难以拆分和测试等问题;

3.React中的JSX是什么?
JSX是JavaScript XML的缩写,它允许我们在JavaScript代码中写类似HTML的语法。这些HTML样式的代码最终会被转换成React元素。

4.React中的组件是什么?
组件是React应用的构建块。它们是独立且可重用的代码片段,用于定义UI的一部分。组件可以是类组件或函数组件,并且可以维护自己的状态和生命周期。

5.React中的state和props的区别
在React中,state是组件内部的状态,可以被组件自身管理和更改。而props(属性)是从父组件传递给子组件的数据,子组件不能修改接收到的props(单向数据流)。

6.什么是生命周期方法,举例说明一些常用的生命周期方法
生命周期方法是React组件在其生命期内可以调用的一系列方法。常见的生命周期方法包括componentDidMount()(组件挂载后调用),componentDidUpdate()(组件更新后调用)和componentWillUnmount()(组件卸载前调用)。

7.解释React中的虚拟DOM是什么
虚拟DOM是内存中的DOM表示。React使用虚拟DOM来优化DOM的更新过程。它通过比较新旧虚拟DOM的差异,并仅更新实际DOM中改变的部分,提高应用性能。

8.为什么React中的列表元素需要一个唯一的key
在React中,列表元素需要一个唯一的key来帮助React识别哪些项已经改变、添加或删除。这提高了渲染列表的性能,尤其是在进行列表项的重新排序或操作时。

9.解释React中的hooks,简述项目中常用的hooks
Hooks是React 16.8引入的新特性,它允许你在不编写类的情况下使用state和其他React特性。常用的hooks包括useState、useEffect和useContext,useMemo,useCallBack,useRef。
useState:用于添加组件的状态,并在状态改变时重新渲染组件。
useEffext: 用于处理组件的副作用,比如网络请求、监听事件、查找dom等。
useContext:用于跨越组件层级直接传递变量,实现数据共享。

useContext:
首先创建一个Context:
import React, { createContext } from 'react';
const ThemeContext = createContext('light');
import React, { useContext } from 'react';
function ExampleComponent() {
  // 使用useContext获取当前的主题
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
}

useMemo:用于缓存某个值,这个值依赖于其他的某些值,只有当这些值发生变化时,缓存的值才会更新。(性能优化)

import React, { useMemo } from 'react';
function Component() {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);
  const c = useMemo(() => a * b, [a, b]);
  return (
    <>
      {c}
      <button onClick={() => setA(a + 1)}>Increase A</button>
      <button onClick={() => setB(b + 1)}>Increase B</button>
    </>
  );
}

useCallBack:用于缓存一个函数,这个函数依赖于其他的某些值,只有当这些值发生变化时,缓存的函数才会更新。(性能优化)

import React, { useCallback } from 'react';
function Component() {
  const [a, setA] = useState(1);
  const multiply = useCallback((b) => a * b, [a]);
  return (
    <>
      {multiply(5)}
      <button onClick={() => setA(a + 1)}>Increase A</button>
    </>
  );
}

useRef:可以创建一个可变ref对象,这个对象在组件的整个生命周期内不会改变,可以用来存储一些不应该因为状态变化而变化的值或函数。

import React, { useRef } from 'react';
function Component() {
  const ref = useRef(null);
  useEffect(() => {
    ref.current.focus();
  }, []);
  return (
    <input ref={ref} />
  );
}

11.如何优化React应用的性能?
优化React应用的性能可以通过多种方式实现,例如使用不可变数据结构、利用shouldComponentUpdate或React.memo避免不必要的渲染、使用懒加载组件以及合理使用hooks和Context等。

12.React中的高阶组件(HOC)是什么
高阶组件(HOC)是一种模式,它接收一个组件并返回一个新组件。HOC用于逻辑复用,它可以向组件添加额外的props或功能,而不必修改组件本身

13.解释React中的纯组件
纯组件(PureComponent)是React中的一种组件。与常规组件相比,纯组件通过对props和state的浅比较来避免不必要的渲染。当纯组件的props或state发生变化时,只有在这些变化不是浅层的时,组件才会重新渲染。一个纯组件是一个不包含任何副作用(例如网络请求,本地存储修改等)的组件。它只根据它的props来渲染视图。

17. React 的生命周期方法有哪些 ?
1)componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。
2)componentDidMount:在第一次渲染之后执行可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。
3)componentWillReceiveProps:在初始代render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于业组件状态更新时子组件的重新渲染。
4)shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 state 或props 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。
5)componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前执行。
6)componentDidUpdate:它主要用于更新DOM以响应props或state更改。
7)componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器。

19.使用 React Hooks 好处是啥 ?
Hook5 通常支持提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染 props 的负担。
Hook5 可以轻松地操作函数组件的状态,而不需要将它们转换为类组件。
避免使用生命周期方法。

20. React 中的 usestate()是什么?
useState 是一个内置的 React Hook。useState(0)返回一个元组,其中第一个参数count是计数器的当前状态,setCounter提供更新计数器状态的方法。
咱们可以在任何地方使用setCounter方法更新计数状态在这种情况下,咱们在setCount函数内部使用它可以做更多的事情,使用 Hooks,能够使咱们的代码保持更多功能,还可以避免过多使用基于类的组件。

useState为什么返回一个数组?
(变量命名问题,方便解构赋值和多次使用,降低复杂度)如果 useState 返回数组,那么你可以顺便对数组中的变量命名,代码看起来也比较干净。而如果是对象的话返回的值必须和 useState 内部实现返回的对象同名,这样你只能在 function component 中使用一次,想要多次使用 useState 必须得重命名返回值。

21.当调用setState时,React render是如何工作的 ?
咱们可以将"render"分为两个步骤
(1)虚拟 DOM 渲染:当render方法被调用时,它返回一个新的组件的虚拟DOM 结构。当调用setState()时,render会被再次调用,因为默认情况shouldComponentUpdote总是返回true,所以默认情况下 React 是没有优化的。
(2)原生 DOM 渲染:
React 只会在虚拟DOM 中修改真实DOM 节点,而且修改的次数非常少–这是很棒的React特性,它优化了真实DOM 的变化,使React变得更快。

23.React受控组件和非受控组件 ?
在 HTML中,表单元素如、和通常维护自己的状态,并根据用户输入进行更新。当用户提立表单时,来自上述元素的值将随表单一起发送。
而 React 的工作方式则不同。包含表单的组件将跟踪其状态中的输入值,并在每次回调函数(例如onChonge)触发时重新渲染组件,因为状态被更新。以这种方式由React 控制其值的输入表单元素称为受控组件。

24、什么是强缓存和协商缓存?
强缓存:直接从本地副本比对读取, 不去请求服务器 ,返回的状态码是 200 。
协商缓存: 会去服务器比对 ,若没改变才直接读取本地缓存,返回的状态码是 304 。
强缓存主要包括 expires 和 cache-control 。 expires 是 HTTP1.0 中定义的缓存字段。 当我们请求一个资源,服务器返回时,可以在 Response Headers 中增加 expires 字段表示资源的过期时间

27.使用箭头函数的好处?
(1)语法简洁:箭头函数的语法比传统的函数声明或函数表达式更简洁。
(2)不绑定 this:箭头函数不会创建自己的 this 值。在箭头函数内部,this 与封闭 词法环境的 this 值相同。这解决了在事件处理器和回调函数中使用 this 的问题。
(3)不绑定 arguments:箭头函数不会创建自己的 arguments 对象。它会从封闭 的词法环境中获取 arguments。
(4)不可以当作构造函数:箭头函数不能用作构造函数,不能使用 new 关键字。
没有 prototype 属性:由于箭头函数不能用作构造函数,所以它也没有 prototype 属性。
(5)不支持 yield 关键字:箭头函数不能用作生成器函数。
总的来说,箭头函数提供了一种更简洁、更方便的函数语法,特别适合用于那些需要匿名函数的场景。
28.call和apply的区别和相同点?
相同:
(1)都可以改变this的指向。
(2)第一个参数都是this要指向的对象。
不同:参数传递的方式不同,call接受参数列表(多个参数),而apply则接受参数数组。

29.有哪些设计模式
(1)工厂模式:假设有一份很复杂的代码需要用户去调用,但是用户并不关心这些复杂的代码,只需要你提供给我一个接口去调用,用户只负责传递需要的参数,至于这些参数怎么使用,内部有什么逻辑是不关心的,只需要你最后返回我一个实例。这个构造过程就是工厂。
(2)单例模式:单例模式的核心就是保证全局只有一个对象可以访问,比如全局缓存、全局状态管理等等这些只需要一个对象,就可以使用单例模式。
(3)适配器模式:用来解决两个接口不兼容的情况,不需要改变已有的接口,通过包装一层的方式实现两个接口的正常协作。vue中的computed属性父子组件的时间戳日期转换。
(4)装饰器模式:不需要改变已有的接口,作用是给对象添加功能。
(5)代理模式:为了控制对对象的访问,不让外部直接访问到对象。比如事件代理就用到了代理模式。
(6)发布-订阅模式:通过一对一或者一对多的依赖关系,当对象发生改变时,订阅方都会收到通知。比如我们点击一个按钮触发了点击事件就是使用了该模式。
(7)外观模式:提供了一个接口,隐藏了内部的逻辑,更加方便外部调用。
(8)策略模式:表单验证、存在大量 if-else 场景、各种重构等。

预售活动,全场 9.5 折
大促活动,全场 9 折
返场优惠,全场 8.5 折
限时优惠,全场 8const activity = (type, price) => {
 if (type === 'pre') {
   return price * 0.95;
  } else if (type === 'onSale') {
   return price * 0.9;
  } else if (type === 'back') {
   return price * 0.85;
  } else if (type === 'limit') {
   return price * 0.8;
  }
}
//使用策略模式
const activity = new Map([
 ['pre', (price) => price * 0.95],
  ['onSale', (price) => price * 0.9],
  ['back', (price) => price * 0.85],
  ['limit', (price) => price * 0.8]
]);
const getActivityPrice = (type, price) => activity.get(type)(price);
activity.set('newcomer', (price) => price * 0.7);

30.http状态码?

2开头 (请求成功)表示成功处理了请求的状态代码。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 
201 (已创建) 请求成功并且服务器创建了新的资源。 
202 (已接受)服务器已接受请求,但尚未处理。 
203 (非授权信息)服务器已成功处理了请求,但返回的信息可能来自另一来源。 
204 (无内容)服务器成功处理了请求,但没有返回任何内容。 
205 (重置内容)服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
301 (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GETHEAD 请求的响应)时,会自动将请求者转到新位置。
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 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
500 (服务器内部错误)  服务器遇到错误,无法完成请求。 
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
504 (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
505HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

31.setState是同步还是异步的?
setState在合成事件(它们将不同浏览器的行为合并为一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性。)和生命周期函数中是异步的,在原生事件和定时器中都是同步的。
原生事件:js的原生事件,如document.addEventListener。
合成事件:React有自己的一套事件机制,它重新封装了绝大部分的原生事件。
setState本身不分同步或者异步,而是取决于是否处于batch update中。组件中的所有函数在执行时临时设置一个变量isBatchingUpdates = true,当遇到setState时,如果isBatchingUpdates是true,那么setState就是异步的,如果是false,那么setState就是同步的。那么什么时候isBatchingUpdates会被设置成false呢?
(1)当函数运行结束时isBatchingUpdates = false
(2)当函数遇到setTimeout、setInterval时isBatchingUpdates = false
(3)当dom添加自定义事件时isBatchingUpdates = false
32.父子组件的useEffec哪个先执行?
先执行子组件再执行父组件。react保证了每次运行useffect的同时,DOM都已经更新完毕。有一些场景,需要父组件的执行顺序在子组件前面,可以考虑一下使用useLayoutEffect
33.react组件之间的通信方式有哪些?
父组件 => 子组件:
1、Props
2、Instance Methods - refs
子组件 => 父组件:
3、Callback Functions - 回调函数
4、Event Bubbling - 事件冒泡机制
5、使用 useImperativeHandle 和 forwardRef,另一种方法是使用React的useImperativeHandle Hook 和 forwardRef 高阶组件。首先,在子组件中使用useImperativeHandle暴露一个方法供父组件调用。然后,在父组件中,你需要使用useRef创建一个引用,并将其作为属性传递给子组件。这样,你就可以通过这个引用访问到子组件的方法。
兄弟组件之间:
6、Parent Component - 利用父组件通信
不太相关的组件之间:
7、Context
8、Portals - 适用 Tooltip、Modal、Popup等
9、Global Variables - 全局变量
10、Observer Pattern - 观察者模式
11、Redux/mobx等

34.axios的封装
自定义配置:封装axios时,可以定义一些默认配置,如基础URL、请求头、超时时间等。
拦截器:使用拦截器处理请求和响应,例如添加统一的错误处理、请求日志记录等。
错误处理:封装时应该考虑异常处理,确保在请求失败时能够优雅地处理错误。如

// 创建一个axios实例
const axiosInstance = axios.create({
 baseURL: 'https://api.example.com', // 基础URL
 timeout: 5000, // 请求超时时间
 headers: {'Authorization': 'Bearer token'}, // 请求头设置
});
// 请求拦截器,可以在发送请求之前处理一些逻辑
axiosInstance.interceptors.request.use(config => {
 // 在这里可以添加请求前的处理逻辑,例如添加请求日志等
 console.log('Request intercepted:', config);
 return config;
}, error => {
 // 对请求错误做些什么
 console.error('Request error:', error);
 return Promise.reject(error);
});
// 响应拦截器,可以在接收到响应之后处理一些逻辑
axiosInstance.interceptors.response.use(response => {
 // 在这里可以统一处理响应数据,例如统一转换成JSON等格式
 return response.data;
}, error => {
 // 对响应错误做些什么,例如统一错误提示等
 console.error('Response error:', error);
 return Promise.reject(error);
});
// 使用封装后的axios实例发起请求
export function fetchData(url, params) {
 return axiosInstance.get(url, { params })
   .catch(error => {
     // 这里可以添加更具体的错误处理逻辑,比如重试机制等
     console.error('Fetch data failed:', error);
     throw error; // 或者返回一个特定的错误对象等操作
   });
}

35.ts和js的区别
(1)静态类型检查:TS 支持静态类型检查,它可以在编译时检查类型错误,从而减少运行时错误和调试时间。而 JS 是动态类型语言,类型检查是在运行时进的。
(2)类和接口:TS 支持类和接口,这些是 JS 不支持的概念。通过类和接口,TS 可以更好地支持面向对象编程和模块化开发。
(3)运行环境。JavaScript直接在浏览器中运行,而TypeScript需要先被编译成JavaScript代码才能在浏览器中执行。
(4) 新特性支持:TS 支持最新的 ECMAScript(ES)规范,包括 ES6、ES7、ES8 等。而 JS 的新特性需要等到浏览器或者运行环境支持后才能使用。

36.styleComponent
随着组件化时代的来临,前端应用开始从组件的层面对 CSS 进行封装:也就是通过 JS 来声明、抽象样式从而提高组件的可维护性;在组件加载时动态的加载样式,动态生成类名从而避免全局污染。
37.flex 1的三个参数
(1)flex-grow拉伸因子(默认值:0)
(2)flex-shrink收缩规则(默认值:1)
(3)flex-basis伸缩基数(默认值: auto)
38:回调函数相较于promise有哪些问题?
回调函数:当您有多个异步操作需要依次执行时,回调函数可能导致“回调地狱”(Callback Hell)或“金字塔问题”(Pyramid of Doom),代码因多层嵌套而变得难以阅读和维护。
promise:提供了一种更优雅的方式来处理异步操作,使代码更易于理解和维护。它通过 .then() 和 .catch() 方法解决了回调地狱的问题,并允许您以链式方式组织代码。
39:浏览器兼容性问题处理,性能问题,缓存。
(1)统一CSS样式。例如,设置统一的margin和padding值,以及清除默认的边框等。
(2)针对特定浏览器的兼容性问题,提供特定的CSS或JavaScript解决方案。例如,对于IE6下的float标签显示问题,可以通过调整display属性或加入特定的CSS规则来解决。
(3)使用浏览器的兼容模式设置。大多数浏览器允许切换到兼容性模式,以解决与旧版网页的兼容性问题。
(4)对于开发者,可以使用在线工具(如Can I Use)来检查各种浏览器对CSS、JavaScript等特性的支持情况,以确保网页在不同浏览器中的兼容性。

39:如何提升浏览器性能。

  1. 使用内容分发网络(CDN)
    内容分发网络可以减少资源加载时间,尤其是对于静态资源如图片和脚本文件。CDN通过全球分布的服务器缓存内容,减少了数据传输的延迟。
  2. 图片优化
    使用格式如WebP的现代图片格式,这些格式在保持图像质量的同时,提供更高的压缩率。使用工具如TinyPNG来压缩图片。
  3. 懒加载图片和视频
    只有当用户滚动到它们的位置时,再加载图片和视频。这样可以减少初始页面加载时间。
  4. 最小化和压缩CSS和JavaScript文件
    使用工具如Webpack或Gulp来最小化和压缩资源。这可以减少文件大小,加快下载速度。
  5. 使用浏览器缓存
    通过设置合理的缓存策略,可以使用户在二次访问时更快地加载网站。
  6. 减少HTTP请求
    合并文件和使用雪碧图来减少页面发起的总HTTP请求数。
  7. 使用异步或延迟加载脚本
    将JavaScript标记为异步(async)或延迟(defer)来提高加载性能。
  8. 优化CSS选择器
    避免深层次和复杂的CSS选择器,这些选择器会增加浏览器的渲染时间。
  9. 使用Web字体优化
    选择性地加载字体文件,并尽可能使用系统字体。
  10. 使用虚拟滚动或分页
    对于长列表,使用虚拟滚动或分页可以大大减少DOM节点数量。
  11. 避免使用大量的DOM操作
    频繁的DOM操作会降低页面性能。使用文档片段和其他优化方法来减少这些操作。
  12. 使用Web Workers进行复杂计算
    将复杂的计算任务移至Web Workers,避免阻塞主线程。
  13. 优化重排和重绘
    避免不必要的DOM和样式更改,这些更改可能会导致页面重排和重绘。
  14. 使用请求节流和防抖技术
    限制事件处理函数的频繁调用,特别是对于resize和scroll事件。
  15. 监控和分析性能
    使用工具如Google Chrome的Lighthouse和Performance标签来监控和分析网站性能。

40:xss攻击和CSRF攻击
(1)侧重点:
XSS攻击注重于通过在受害者的浏览器中注入恶意脚本,利用受害者的身份执行非授权操作。
CSRF攻击则侧重于伪造用户的身份,强制用户以受害者的名义执行未经授权的操作。
(2)攻击源:
XSS攻击通常发生在用户输入的数据被插入到网页中,如评论框、搜索框等,当其他用户查看这些数据时,恶意脚本被执行。
CSRF攻击则是在用户已经登录的网站上,通过诱导用户点击恶意链接或按钮,利用用户已有的会话信息(如Cookie)来执行未授权的操作。
(3)传播范围:
XSS攻击可以影响大量用户,因为恶意脚本被存储在服务器上,任何访问该页面的用户都可能受到影响。
CSRF攻击则更加针对个人,因为它依赖于用户点击特定的链接或按钮来触发攻击。
(4)攻击形式:
XSS攻击通常通过在页面上插入恶意脚本(如JavaScript)来实现,这些脚本可以在用户的浏览器中执行。
CSRF攻击则通过诱导用户访问恶意网站或点击恶意链接来实现,利用的是用户已有的登录状态。
40:vue2和vue3的区别
(1)响应式原理的不同。Vue 2使用Object.defineProperty进行数据劫持,这种方式对新增属性和数组变动的检测有限制。相比之下,Vue 3采用了ES6的Proxy API,可以更有效地监控数据变化,包括对象和数组的内部变动。
(2)组件模板和碎片(Fragments)。Vue 3允许组件模板有多个根节点,而Vue 2要求只有一个根节点。这种变化简化了对复杂组件结构的处理。
(3)API类型的不同。Vue 3引入了Composition API,这是一种基于函数的API风格,相比Vue 2的Options API,它提供了更灵活和组织性更好的代码结构。
生命周期钩子的不同。Vue 3的生命周期钩子与Vue 2有所不同,特别是在使用组合式API时,需要显式引入生命周期钩子。
(4)性能提升。Vue 3在性能方面有显著提升,包括初次渲染和更新的速度提升,以及内存使用的减少。
(5)其他新特性和改进。Vue 3增加了Teleport组件,用于将部分DOM移动到Vue应用之外的位置,如对话框。此外,对TypeScript的支持更加友好,提供了更好的类型推断和检查。还有对虚拟DOM算法的优化、更好的Tree Shaking支持等。
:echarts参数有哪些?axios未登录重定向怎么实现?
:redux、vuex
:webpack、nodeJs
:总结项目

你可能感兴趣的:(react.js,前端,前端框架)