自学内容网 自学内容网

面试题总结

1.前端的数据类型有哪些

字符串(String)、‌ 数字(Number)、‌ 布尔值(Boolean)、‌ 数组(Array)、‌ 对象(Object)、‌ 空值(Null)、‌ 未定义(Undefined)和函数(Function)

2.说说你了解的 flex 布局吧

  • flex-direction: row | row-reverse | column | column-reverse;
    row(默认值):主轴为水平方向,起点在左端(项目从左往右排列)。
    row-reverse:主轴为水平方向,起点在右端(项目从右往左排列)。
    column:主轴为垂直方向,起点在上沿(项目从上往下排列)。
    column-reverse:主轴为垂直方向,起点在下沿(项目从下往上排列)
    flex-wrap: nowrap | wrap | wrap-reverse;
    nowrap(默认):不换行(列)。
    wrap:主轴为横向时:从上到下换行。主轴为纵向时:从左到右换列。
    wrap-reverse:主轴为横向时:从下到上换行。主轴为纵向时:从右到左换列。
    justify-content(主轴上的对齐方式): flex-start | flex-end | center | space-between | space-around;
    flex-start(默认):与主轴的起点对齐。
    flex-end:与主轴的终点对齐
    center:与主轴的中点对齐。
    space-between:两端对齐主轴的起点与终点,项目之间的间隔都相等。
    space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
    align-items: flex-start | flex-end | center | baseline | stretch;
    flex-start:交叉轴的起点对齐。
    flex-end:交叉轴的终点对齐。
    center:交叉轴的中点对齐。
    baseline: 项目的第一行文字的基线对齐。
    stretch(默认值):如果项目未设置高度或设为 auto,项目将占满整个容器的高度。
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
    flex-start:与交叉轴的起点对齐。
    flex-end:与交叉轴的终点对齐。
    center:与交叉轴的中点对齐。
    space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
    space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
    stretch(默认值):主轴线占满整个交叉轴。

3.说一下cookie,sessionStorage,localStorage 区别?

在这里插入图片描述
在这里插入图片描述

4.数组常用方法

在这里插入图片描述
在这里插入图片描述

5.说一说 map 和 forEach 的区别

map和forEach的主要区别在于它们的返回值、‌对原数组的影响、‌链式操作能力、‌以及使用场景。‌
返回值:‌
map方法有返回值,‌并且必须返回一个数组。‌它返回一个新的数组,‌这个新数组是由原始数组的每个元素通过提供的函数处理后生成的结果组成的。‌
forEach方法没有返回值,‌它直接对原始数组进行操作,‌不会返回新的数组。‌它的主要目的是遍历数组并对每个元素执行某个操作,‌而不是生成新的数据结构。‌
对原数组的影响:‌
map方法不会修改原始数组,‌它总是返回一个新的数组。‌即使原始数组中的元素是引用类型,‌map也只是对引用类型的值进行浅拷贝,‌并不会改变原始数组中的引用对象本身。‌
forEach方法会直接修改原始数组,‌因为它没有返回值,‌所有的操作都是直接在原始数组上进行的。‌
链式操作能力:‌
map方法因为返回一个数组,‌所以支持链式操作,‌可以与其他数组方法(‌如filter、‌reduce等)‌组合使用,‌实现更复杂的操作。‌
forEach方法不支持链式操作,‌因为它没有返回值,‌无法进行链式调用。‌
使用场景:‌
当你需要创建一个新的数组,‌并且希望原始数据不被修改时,‌应使用map方法。‌例如,‌你可以使用map方法将数组中的每个元素乘以2,‌得到一个新的数组。‌
当你只是想遍历数组并对每个元素执行某种操作,‌而不关心返回的新数据结构时,‌可以使用forEach方法。‌例如,‌打印每个数组元素的值或者对每个元素进行一些副作用操作(‌如改变DOM元素的状态)‌。‌
总的来说,‌选择使用map还是forEach取决于你的具体需求:‌如果你需要生成一个新的数据结构,‌并且希望保持原始数据的完整性,‌应使用map;‌如果你只是想对原始数据进行某种操作而不关心返回的数据结构,‌那么forEach是更好的选择

6.forEach可以结束循环吗

在JavaScript中,‌forEach循环不能直接通过break或return语句来结束。‌这是因为forEach是一种高阶函数,‌它接受一个函数作为参数,‌并对数组中的每个元素执行该函数。‌由于forEach的设计初衷是对数组中的每个元素执行一次提供的函数,‌因此它没有提供内置的机制来提前停止或中断循环。‌尽管如此,‌有几种方法可以用来模拟终止forEach循环的效果:‌
使用return语句:‌虽然return语句不会直接终止forEach循环,‌但它可以在回调函数内部使用,‌以退出当前迭代并继续到数组中的下一个元素。‌这种方法虽然不能完全终止循环,‌但可以用来模拟类似的效果。‌
使用异常处理:‌通过抛出自定义的异常,‌可以在捕获到该异常后终止forEach循环。‌这种方法虽然不是常规做法,‌但技术上可行,‌尽管它可能会影响代码的可读性和错误处理。‌
使用其他循环结构:‌如果需要在特定条件下终止循环,‌可以考虑使用for…of循环代替forEach。‌for…of循环支持使用break语句来终止循环,‌从而提供更灵活的控制。‌
综上所述,‌虽然forEach循环本身不支持直接终止,‌但通过上述方法可以模拟或实现类似的效果

7.防抖和节流

防抖:用户触发事件过于频繁,会等到停止最后一次操作后一段时间后才执行
节流:控制高频事件执行次数,限制流量,每隔多少秒执行一次

8.前端跨页面通信,你知道哪些方法?

https://blog.csdn.net/weixin_43908649/article/details/134088900?spm=1001.2014.3001.5501

9.遇到过跨域的问题都是怎么解决的

同源策略:浏览器使用同源策略来限制不同源之间的交互,同源指的是协议、域名和端口号完全相同。
前端跨域问题的解决方法主要包括jsonp、‌CORS、‌代理、‌postMessage、‌WebSocket协议跨域、‌nginx代理跨域、‌nodejs中间件代理跨域等。‌
jsonp跨域:‌利用浏览器对
标签没有跨域限制的特性,‌通过动态创建script标签,‌并设置其src属性为跨域请求的URL,‌同时传递一个回调函数名作为参数。‌服务器端接收到请求后,‌将响应数据以JavaScript代码的形式返回,‌调用客户端传递的回调函数,‌并将数据作为参数传入。‌这种方法简单易实现,‌但只能发送GET请求,‌且存在安全风险,‌如易受到XSS攻击12。‌
CORS(‌跨域资源共享)‌:‌CORS是一种W3C标准,‌允许服务器明确地允许来自其他源的请求。‌通过在HTTP请求头中设置Access-Control-Allow-Origin等字段,‌可以指定哪些源有权限进行跨域访问。‌CORS机制灵活且安全,‌是现代Web应用中最常用的跨域解决方案4。‌
代理跨域:‌通过设置代理服务器来转发请求,‌实现跨域访问。‌这包括使用nginx代理跨域和nodejs中间件代理跨域。‌代理服务器接收客户端的请求,‌然后将请求转发给目标服务器,‌并将响应返回给客户端,‌从而绕过浏览器的同源策略限制。‌这种方法适用于开发阶段和需要临时解决方案的场景23。‌
postMessage跨域:‌通过window.postMessage方法可以实现跨域窗口之间的消息传递。‌这种方法适用于不同框架或页面之间的数据交换,‌但需要目标窗口配合接收消息3。‌
WebSocket协议跨域:‌WebSocket协议本身支持跨域通信,‌无需为每个请求设置额外的头部信息。‌通过建立WebSocket连接,‌可以实现实时、‌双向的通信,‌适用于需要实时交互的应用场景3。‌
综上所述,‌解决前端跨域问题的方法多样,‌选择哪种方法取决于具体的应用场景和需求。‌在开发阶段,‌为了简化开发流程,‌可能会使用到jsonp和代理等方法;‌而在生产环境中,‌为了保证安全性和性能,‌通常会采用CORS作为主要的跨域解决方案12。‌

10.react 的通信方式有哪些

React的通信方式主要包括以下几种:‌
Props:‌这是最常用的方式,‌用于在组件之间传递信息。‌通过props,‌数据可以从父组件传递到子组件中。‌这是React的核心功能之一,‌也是React的基础知识。‌
回调函数:‌用于子组件向父组件传递信息。‌父组件可以通过向子组件传递一个函数作为属性,‌子组件可以使用这个函数来把数据传给它的父组件。‌
事件冒泡:‌虽然这不是React特有的概念,‌但DOM的事件机制可以用于从子组件发送数据到父组件。‌当在子组件中触发DOM事件时,‌父组件中的事件监听器可以捕获这些事件。‌
Context:‌这是一种为整个子树提供数据的方式,‌可以用于跨组件通信。‌Context可以在树中向下传递数据(‌从父组件到子树)‌,‌但需要配合回调函数来向上传递数据(‌从子树到父组件)‌。‌
全局变量:‌虽然使用全局变量不是最佳实践,‌但在某些情况下,‌它可以作为一种简单的通信机制。‌然而,‌这通常被视为一种权宜之计,‌而不是长期的解决方案。‌
观察者模式:‌这是一种软件设计模式,‌允许一个对象发送数据到多个其他对象。‌这在所有组件之间通信时非常有用,‌无论它们是否是父子组件或平级组件。‌
Redux:‌对于更复杂的状态管理,‌Redux提供了一个集中存储应用状态的地方,‌并提供了从组件到全局状态的双向数据流。‌这对于跨组件、‌跨页面共享数据非常有用。‌
节点事件模块(‌node的事件模块)‌:‌对于服务器端渲染或特定于Node.js的应用,‌可以使用node的events模块来实现单例通信。‌
选择合适的通信方式取决于具体的应用场景和需求。‌例如,‌对于简单的父子组件通信,‌使用props和回调函数就足够了;‌而对于更复杂的跨组件通信或状态管理,‌可能需要考虑使用Context、‌Redux或node的事件模块等

11.react hooks 你都了解哪些

在这里插入图片描述

如何解决useState状态异步更新的问题
useEffect不同依赖项有什么不同
可以把对象作为 useEffect 的依赖项吗
写过哪些自定义hooks(自定义封装秒数倒计时的 hook)

12.react 的生命周期都有哪些

constructor 组件被创建时会首先调用组件的构造方法 用于初始化 state,以及为事件处理程序绑定 this
componentWillMount 组件挂载之前触发 弃用
render 渲染组件 render 里面不能调用 this.setState()
componentDidMount 组件挂载后触发 只会被调用一次,向服务器端发送网络请求,处理依赖 DOM 节点的操作(虚拟 DOM 已经挂载到了页面上成为了真实 DOM)
componentWillReceiveProps 组件更新 弃用,只有在 props 引起的组件更新时被调用
shouldComponentUpdate 组件更新 决定组件是否继续执行更新过程,可以用来减少组件不必要的渲染,从而优化组件的性能
componentWillUpdate 组件将要更新数据时触发 获取的 props 和 state 都是新的值
componentDidUpdate 组件数据更新完成时触发 获取的 props 和 state 都是上一次的值,可以操作更新后的 DOM
componentWillUnmount 组件卸载及销毁之前调用 执行 一些清理工作(清理定时器)
使用 useState 解决函数式组件没有 state 的问题,使用 useEffect 解决没有生命周期的问题
useEffect(() => { }, []); 首次页面加载时执行
useEffect(() => {}); 任意属性变更时执行
useEffect(() => {},[count]); 依赖项变化时执行
useEffect(() => {return () => clearInterval(interval)},[]); 组件卸载或销毁时执行

13.react 性能优化的手段

1 Reac.memo 缓存组件
2 使用 useMemo 缓存大量的计算
3 避免使用 内联对象
4 避免使用 匿名函数
5 延迟加载不是立即需要的组件
6 调整CSS而不是强制组件加载和卸载
7 使用React.Fragment避免添加额外的DOM
8 使用React.PureComponent , shouldComponentUpdate

14.使用过 vuex 吗?都在什么场景下使用的

例如登录状态、加入购物车、音乐播放

15.Vue的虚拟dom和diff算法

https://blog.csdn.net/weixin_43908649/article/details/134219084?spm=1001.2014.3001.5501

16.vue 生命周期有几个阶段

它可以总共分为 8 个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
beforeCreate:是 new Vue( ) 之后触发的第一个钩子,在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问。
created:在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发 updated 函数。可以做一些初始数据的获取,在当前阶段无法与 DOM 进行交互,如果非要想,可以通过 vm.$nextTick 来访问 DOM 。
beforeMount:发生在挂载之前,在这之前 template 模板已导入渲染函数编译。而当前阶段虚拟 DOM 已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发 updated。
mounted:在挂载完成后发生,在当前阶段,真实的 DOM 挂载完毕,数据完成双向绑定,可以访问到 DOM 节点,使用 $refs 属性对 DOM 进行操作。
beforeUpdate:发生在更新之前,也就是响应式数据发生更新,虚拟 DOM 重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。
updated:发生在更新完成之后,当前阶段组件 DOM 已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。
beforeDestroy:发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。
destroyed:发生在实例销毁之后,这个时候只剩下了 DOM 空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁

17.多组件(父子组件)中生命周期的调用顺序说一下

组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。组件的销毁操作是先父后子,销毁完成的顺序是先子后父。
加载渲染过程:父 beforeCreate->父 created->父 beforeMount->子 beforeCreate->子 created->子 beforeMount- >子 mounted->父 mounted
子组件更新过程:父 beforeUpdate->子 beforeUpdate->子 updated->父 updated
父组件更新过程:父 beforeUpdate -> 父 updated
销毁过程:父 beforeDestroy->子 beforeDestroy->子 destroyed->父 destroyed

18.说一下 watch 与 computed 的区别是什么?以及他们的使用场景分别是什么?

都是观察数据变化的(相同)
计算属性将会混入到 vue 的实例中,所以需要监听自定义变量;watch 监听 data 、props 里面数据的变化;
computed 有缓存,它依赖的值变了才会重新计算,watch 没有;
watch 支持异步,computed 不支持;
watch 是一对多(监听某一个值变化,执行对应操作);computed 是多对一(监听属性依赖于其他属性)
watch 监听函数接收两个参数,第一个是最新值,第二个是输入之前的值;
computed 属性是函数时,都有 get 和 set 方法,默认走 get 方法,get 必须有返回值(return)
watch 的 参数:
deep:深度监听
immediate :组件加载立即触发回调函数执行
computed 缓存原理:
conputed 本质是一个惰性的观察者;当计算数据存在于 data 或者 props 里时会被警告;
vue 初次运行会对 computed 属性做初始化处理(initComputed),初始化的时候会对每一个 computed 属性用 watcher 包装起来 ,这里面会生成一个 dirty 属性值为 true;然后执行 defineComputed 函数来计算,计算之后会将 dirty 值变为 false,这里会根据 dirty 值来判断是否需要重新计算;如果属性依赖的数据发生变化,computed 的 watcher 会把 dirty 变为 true,这样就会重新计算 computed 属性的值。

19.看简历,之前也做过【广联达】项目前端的负责人,你如何与团队成员沟通,‌以确保项目高效顺利的进行和团队的和谐与动力

20.之前项目中的最佳实践或遇到的问题,怎么实现或怎么解决的?


原文地址:https://blog.csdn.net/weixin_43908649/article/details/140524077

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!