引言
春招来袭,面对面试中的难题,不少人都感到头疼。本文将分享一些常见的面试问题及应对策略,希望能帮助你在准备过程中更加得心应手,顺利通过面试。让我们一起加油,向着理想offer冲刺吧!🚀
vue3 生命周期
Vue 3 的生命周期钩子函数与 Vue 2 类似,但有一些细微的变化和新增的组合式 API(Composition API)钩子。以下是 Vue 3 的生命周期钩子及其执行顺序:
1. beforeCreate
- 触发时机:在实例初始化之后,数据观测 (data observer) 和事件/侦听器配置之前被调用。
- 用途 :此时组件的
data
和methods
还未初始化,通常用于执行一些初始化操作
2. created
- 触发时机 :在实例创建完成后被立即调用。此时,数据观测 (data observer)、属性和方法的运算、
watch/event
事件回调已经设置完成。 - 用途 :可以访问
data
和methods
,但 DOM 还未生成,通常用于发起异步请求。
3. beforeMount
- 触发时机 :在挂载开始之前被调用,相关的
render
函数首次被调用。 - 用途:此时模板已经编译完成,但尚未将模板渲染到 DOM 中。
4. mounted
- 触发时机:在实例挂载到 DOM 后被调用。此时,组件已经出现在页面中,DOM 已经生成。
- 用途:可以访问 DOM 元素,通常用于操作 DOM 或发起依赖于 DOM 的请求。
5. beforeUpdate
- 触发时机:在数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
- 用途:可以在更新之前访问现有的 DOM,例如手动移除事件监听器。
6. updated
- 触发时机:在数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。
- 用途:可以执行依赖于 DOM 更新的操作,但要注意避免无限循环的更新。
7. beforeUnmount (Vue 2 中的 beforeDestroy
)
- 触发时机:在实例卸载之前调用。
- 用途:此时实例仍然完全可用,通常用于清理工作,如取消定时器、移除事件监听器等。
8. unmounted (Vue 2 中的 destroyed
)
- 触发时机:在实例卸载之后调用。
- 用途:此时所有的指令和事件监听器都已被移除,子实例也都被销毁。
9. errorCaptured
- 触发时机:当捕获一个来自子孙组件的错误时被调用。
- 用途 :可以用于处理组件树中的错误,返回
false
可以阻止错误继续向上传播。
10. renderTracked (开发模式)
- 触发时机:在渲染过程中跟踪到响应式依赖时调用。
- 用途:用于调试,了解哪些依赖被跟踪。
11. renderTriggered (开发模式)
- 触发时机:在响应式依赖触发重新渲染时调用。
- 用途:用于调试,了解哪些依赖触发了重新渲染。
生命周期图示
plaintext
beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeUnmount -> unmounted
总结
Vue 3 的生命周期钩子函数与 Vue 2 类似,但在组合式 API (setup
函数) 中,生命周期钩子是通过 onXXX
函数来使用的。
ref 与 reactive 的区别
ref
和 reactive
都是用来创建响应式数据的方法,但它们的使用场景和工作方式有所不同。
ref
- 用途 :
ref
主要用于创建一个包含值的响应式引用对象。它可以用来包裹基本类型(如字符串、数字等)或对象类型的数据。 - 访问与修改 :由于
ref
创建的是一个对象,因此在模板中可以直接使用,但在 JS 代码中访问其值时需要通过.value
属性来获取或设置值。 - 解构 :当你解构
ref
或者将它传递给函数参数时,你得到的是它的原始值而非响应式的引用。如果需要保持响应性,可以考虑使用toRefs
方法。
reactive
- 用途 :
reactive
是用来创建一个响应式的对象。它使得对象的所有嵌套层次都具有响应性,非常适合用于处理复杂状态管理。 - 访问与修改 :直接通过属性名进行访问和修改即可,不需要像
ref
那样使用.value
。 - 限制:只能对对象(包括数组和普通 JavaScript 对象)进行代理,不能直接作用于基本数据类型。
总结
- 使用
ref
可以更灵活地处理基本类型数据,并且在某些情况下(比如在组合式 API 函数之间共享状态)可能更加方便。 reactive
则提供了一种更为直观的方式来处理对象类型的响应式状态,特别是对于那些拥有多个相关联状态属性的情况。
vue3 组件
在 Vue 3 中,为了提升用户体验和优化应用性能,引入了几个关键组件和特性。以下是这些特性的优化介绍:
-
Transition :
<Transition>
组件用于包裹元素或组件,为它们的进入和离开添加动画效果。Vue 自动检测元素或组件的添加或移除,并应用相应的过渡类名,允许通过 CSS 或 JavaScript 钩子自定义进入和离开时的动画。 -
TransitionGroup : 类似于
<Transition>
,但<TransitionGroup>
适用于一组需要过渡效果的元素或组件。它不仅处理单个元素的进入和离开,还处理列表中元素的变化,如添加、删除或重新排序。使用<TransitionGroup>
包裹的元素必须拥有唯一的key
属性。 -
KeepAlive : 抽象组件
<KeepAlive>
缓存动态组件或路由视图,避免切换时销毁和重建组件,有助于维持组件状态,提高用户体验。可通过include
和exclude
属性指定哪些组件应被缓存。 -
Teleport :
<Teleport>
(之前版本称为 Portal)允许将子组件渲染至 DOM 中的不同位置。不同于常规组件渲染于父组件的内容分发处,<Teleport>
可指定一个目标元素作为挂载点,即使该位置位于组件层次结构之外,也能将内容挂载于此。 -
Suspense : 新增的实验性特性
<Suspense>
,在等待异步依赖(例如异步组件)加载完成前显示备用内容。当组件树的一部分正在等待异步操作完成时,<Suspense>
能展示加载状态或其他占位符内容,直至所有数据准备就绪。
vue-router 中的 router和route
在 Vue.js 中,vue-router
是用于实现单页面应用(SPA)路由管理的官方库router
和 route
是 vue-router
中两个非常重要的概念,它们分别代表不同的对象和用途。
1.router
是什么?
router
是 vue-router
的核心实例,负责管理整个应用的路由。你可以把它想象成一个"路由器",它决定了当你点击一个链接或者改变浏览器地址时,应用应该加载哪个组件。
router
的主要职责:
- 路由配置 :你需要在
router
中定义路由规则,比如/home
对应Home
组件,/about
对应About
组件。 - 导航控制 :
router
提供了导航方法,比如push
、replace
、go
等,用于在代码中跳转到不同的路由。 - 全局钩子 :
router
还支持全局的路由守卫(如beforeEach
、afterEach
),可以在路由跳转前后执行一些逻辑,比如权限校验、页面加载动画等。
router
的常见用法:
- 在项目中,你会先创建一个
router
实例,并配置路由规则。 - 然后将这个
router
实例挂载到 Vue 的根实例中,这样整个应用就具备了路由功能。 - 在组件中,你可以通过
this.$router
访问router
实例,调用它的方法进行导航。
2.route
是什么?
route
是当前激活的路由对象,它包含了当前路由的详细信息。你可以把它理解为一个"快照",记录了当前路由的状态。
route
的主要职责:
- 提供路由信息 :
route
包含了当前路由的路径(path
)、参数(params
)、查询字符串(query
)、哈希值(hash
)等信息。 - 动态路由匹配 :如果你的路由是动态的(比如
/user/:id
),route
会解析出动态参数(如id
),方便你在组件中使用。 - 嵌套路由信息 :
route
还包含了嵌套路由的匹配记录(matched
),方便你处理复杂的路由结构。
route
的常见用法:
- 在组件中,你可以通过
this.$route
访问当前的路由对象。 - 比如,你可以通过
this.$route.params.id
获取动态路由参数,或者通过this.$route.query.search
获取查询字符串。
3. router
和 route
的关系
router
是管理者,route
是被管理者 :router
负责管理路由的跳转和全局配置,而route
是router
跳转后的结果,记录了当前路由的状态。router
改变route
:当你调用router.push
或router.replace
时,router
会根据配置的路由规则,找到匹配的组件,并更新route
对象。route
是只读的 :route
对象是只读的,你不能直接修改它。如果你想改变路由,必须通过router
的方法(如push
、replace
)来实现。
4. 总结
router
是路由的管理者,负责路由的跳转、配置和全局守卫。route
是当前路由的状态对象,提供了当前路由的详细信息。- 它们的关系是:
router
控制路由的跳转,跳转后生成新的route
对象,route
则记录了当前路由的状态。
js 的基本数据类型和引用数据类型
在 JavaScript 中,数据类型可以分为两大类:基本数据类型(原始类型)和引用数据类型(对象类型) 。它们的核心区别在于 存储方式 和 操作方式。
1. 基本数据类型(Primitive Types)
基本数据类型是 JavaScript 中最基础的数据类型,它们的值直接存储在变量中,占用固定的内存空间。基本数据类型是不可变的(immutable),也就是说,一旦创建,它们的值就不能被修改。
JavaScript 中的基本数据类型有以下 7 种: number
、string
、boolean
、null
、undefined
、symbol
、bigint
。
2. 引用数据类型(Reference Types)
引用数据类型是复杂的数据类型,它们的值存储在堆内存中,变量中存储的是指向堆内存中对象的引用(地址)。引用数据类型是可变的(mutable),也就是说,它们的值可以被修改。
JavaScript 中的引用数据类型主要包括: object
、array
、function
等。
3. 基本数据类型 vs 引用数据类型
特性 | 基本数据类型 | 引用数据类型 |
---|---|---|
存储方式 | 值直接存储在栈内存中 | 值存储在堆内存中,变量存储的是引用(地址) |
可变性 | 不可变(immutable) | 可变(mutable) |
比较方式 | 比较的是值 | 比较的是引用(地址) |
复制行为 | 复制的是值 | 复制的是引用 |
内存占用 | 占用固定大小的内存 | 占用不固定的内存,动态分配 |
示例 | let a = 10; |
let obj = { name: "Alice" }; |
4. 注意事项
-
浅拷贝和深拷贝 :
对于引用数据类型,直接赋值只是复制了引用,如果需要复制值,需要使用浅拷贝或深拷贝。
- 浅拷贝:
Object.assign()
或扩展运算符...
。 - 深拷贝:
JSON.parse(JSON.stringify(obj))
或使用工具库(如 Lodash)。
- 浅拷贝:
-
类型检测 :
使用
typeof
可以检测基本数据类型,但对于引用数据类型(如null
、array
),typeof
的结果可能不准确。可以使用instanceof
或Object.prototype.toString.call()
进行更准确的检测。
5. 总结
- 基本数据类型 :
number
、string
、boolean
、null
、undefined
、symbol
、bigint
。 - 引用数据类型 :
object
、array
、function
等。 - 核心区别:基本数据类型存储的是值,引用数据类型存储的是引用。
ts 的基本数据类型
TypeScript 是 JavaScript 的超集,它在 JavaScript 的基础上增加了静态类型系统。TypeScript 的基本数据类型几乎包含了 JavaScript 的所有基本数据类型,并在此基础上增加了一些额外的类型。以下是 TypeScript 中的基本数据类型:
- JavaScript 的原始类型:
number
、string
、boolean
、null
、undefined
、symbol
、bigint
。 - TypeScript 特有的类型:
void
:表示没有任何返回值的类型,通常用于函数返回值。any
:表示任意类型,关闭类型检查。unknown
:表示未知类型,比any
更安全,需要进行类型检查后才能使用。never
:表示永远不会发生的类型,通常用于抛出异常或无限循环的函数。object
:表示非原始类型的对象类型。array
:表示数组类型,可以用两种方式定义:使用类型[]
语法;使用泛型Array<类型>
语法。tuple
:表示元组类型,用于表示固定长度和类型的数组。enum
:表示枚举类型,用于定义一组命名的常量。
- 其他高级类型:
- 联合类型('|'):表示一个值可以是多种类型之一。
- 交叉类型('&'):表示一个值必须同时满足多种类型。
- 字面量类型、类型别名、函数类型
TypeScript 类型 vs JavaScript 类型
- TypeScript 的类型是静态的,在编译时进行类型检查。
- JavaScript 的类型是动态的,在运行时确定。
- TypeScript 的类型系统增强了代码的可读性和可维护性,同时减少了运行时错误。
ts 的泛型和接口
1. 泛型(Generics)
泛型是一种创建可重用组件的方式,它允许我们在定义函数、类或接口时使用类型参数,而不是直接指定具体类型。泛型的核心思想是 参数化类型。
2. 接口(Interfaces)
接口是 TypeScript 中用于定义对象结构的工具。它描述了对象的属性、方法以及它们的类型。接口的核心思想是 定义契约,确保对象符合特定的结构。
tcp 与 udp 的区别
特性 | TCP | UDP |
---|---|---|
全称 | Transmission Control Protocol | User Datagram Protocol |
连接方式 | 面向连接(通过三次握手建立连接) | 无连接 |
可靠性 | 可靠传输(确认、重传、流量控制) | 不可靠传输 |
数据传输方式 | 面向字节流 | 面向报文 |
性能 | 开销大,传输效率较低 | 开销小,传输效率较高 |
头部大小 | 较大(通常 20 字节) | 较小(固定 8 字节) |
顺序保证 | 数据按序到达 | 数据可能乱序到达 |
流量控制 | 支持(滑动窗口机制) | 不支持 |
拥塞控制 | 支持(慢启动、拥塞避免等) | 不支持 |
适用场景 | 文件传输、网页浏览、电子邮件 | 视频流、在线游戏、语音通话 |
总结
- TCP:适合对可靠性要求高的场景,如文件传输、网页浏览等。
- UDP:适合对实时性要求高的场景,如视频流、在线游戏等。
udp 如何实现稳定传输
UDP(User Datagram Protocol)本身是一个无连接、不可靠的传输协议,它不提供数据包的确认、重传、排序和拥塞控制等机制。然而,在某些应用场景中,我们可能需要在 UDP 的基础上实现一定程度的稳定传输。以下是几种常见的实现方式:
-
应用层实现确认和重传机制 在应用层模拟 TCP 的确认(ACK)和重传机制,确保数据包的可靠传输。
-
实现数据包排序 UDP 不保证数据包的顺序,因此需要在应用层实现数据包的排序。
-
实现流量控制 UDP 本身没有流量控制机制,但可以通过应用层实现简单的流量控制。
-
实现拥塞控制 UDP 本身没有拥塞控制机制,但可以通过应用层实现简单的拥塞控制。
-
使用可靠传输协议(如 RUDP、QUIC) 如果应用场景对可靠性要求较高,可以直接使用基于 UDP 的可靠传输协议,如 RUDP(Reliable UDP)或 QUIC(Quick UDP Internet Connections)。
-
结合前向纠错(FEC) 前向纠错(Forward Error Correction,FEC)是一种通过添加冗余数据来纠正传输错误的技术。
介绍 vuex和pinia 的核心结构
1. Vuex 的核心结构
Vuex 是 Vue.js 官方推荐的状态管理库,采用集中式存储管理应用的所有组件的状态。它的核心结构包括以下几个部分:
-
State
- 作用 :存储应用的状态数据,类似于组件的
data
。 - 特点:状态是响应式的,状态变化会自动更新视图。
- 作用 :存储应用的状态数据,类似于组件的
-
Getters
- 作用 :从
state
中派生出一些状态,类似于组件的computed
。 - 特点 :可以对
state
进行计算或过滤,避免重复代码。
- 作用 :从
-
Mutations
- 作用 :用于同步修改
state
的唯一方式。 - 特点 :必须是同步函数,通过
commit
方法调用。
- 作用 :用于同步修改
-
Actions
- 作用 :用于处理异步操作,提交
mutation
来修改state
。 - 特点 :可以包含任意异步操作,通过
dispatch
方法调用。
- 作用 :用于处理异步操作,提交
-
Modules
- 作用 :将
store
分割成模块,每个模块拥有自己的state
、getters
、mutations
和actions
。 - 特点 :适合大型应用,避免
store
过于臃肿。
- 作用 :将
2. Pinia 的核心结构
Pinia 是 Vue.js 的下一代状态管理库,相比于 Vuex,它更轻量、更简单,同时保留了 Vuex 的核心功能。Pinia 的核心结构包括以下几个部分:
-
(1)State
- 作用 :存储应用的状态数据,类似于 Vuex 的
state
。 - 特点:状态是响应式的,可以直接修改。
- 作用 :存储应用的状态数据,类似于 Vuex 的
-
(2)Getters
- 作用 :从
state
中派生出一些状态,类似于 Vuex 的getters
。 - 特点:支持缓存,计算结果会被缓存直到依赖的状态发生变化。
- 作用 :从
-
(3)Actions
- 作用 :用于修改
state
,可以包含同步或异步操作。 - 特点 :没有
mutations
,直接通过actions
修改state
。
- 作用 :用于修改
3. Vuex 和 Pinia 的对比
特性 | Vuex | Pinia |
---|---|---|
核心结构 | State、Getters、Mutations、Actions | State、Getters、Actions |
异步操作 | 通过 Actions 处理 | 直接通过 Actions 处理 |
模块化 | 通过 Modules 实现 | 每个 Store 独立,天然模块化 |
TypeScript 支持 | 需要额外配置 | 原生支持 TypeScript |
API 设计 | 较复杂,学习成本较高 | 更简单直观,学习成本低 |
体积 | 较大 | 更轻量 |
适用场景 | 大型复杂应用 | 中小型应用或需要轻量状态管理的场景 |
如果vuex 刷新后数据消失了怎么办
-
手动持久化状态 : 通过手动将状态保存到
localStorage
或sessionStorage
,并在页面加载时恢复状态。 -
使用插件自动持久化状态 : 可以使用第三方插件(如
vuex-persistedstate
)来自动实现状态的持久化。vuex-persist
是另一个流行的 Vuex 持久化插件,支持更灵活的配置。 -
结合 Cookie 持久化状态 : 如果需要将状态持久化到 Cookie 中,可以使用
js-cookie
库。
node.js 处理多个异步
1. 回调函数(Callback)
回调函数是 Node.js 中最基础的异步处理方式,但容易导致"回调地狱"(Callback Hell)。
缺点:
- 嵌套层级深,代码难以维护。
- 错误处理复杂。
2. Promise
Promise 是 ES6 引入的异步编程解决方案,可以避免回调地狱。
优点:
- 链式调用,代码更清晰。
- 支持统一的错误处理。
3. Async/Await
async/await
是 ES7 引入的语法糖,基于 Promise,使异步代码看起来像同步代码。
优点:
- 代码更简洁,易读性高。
- 错误处理更直观。
4. 并行处理多个异步操作
如果需要并行处理多个异步操作,可以使用以下方法:
(1)Promise.all
Promise.all
可以并行执行多个 Promise,并在所有 Promise 完成后返回结果。
特点:
- 如果其中一个 Promise 失败,整个
Promise.all
会立即失败。
(2)Promise.allSettled
Promise.allSettled
会等待所有 Promise 完成,无论成功或失败。
特点:
- 不会因为某个 Promise 失败而中断。
(3)Promise.race
Promise.race
返回最先完成的 Promise 的结果(无论成功或失败)。
特点:
- 适合超时控制或竞速场景。
5. 事件驱动(EventEmitter)
Node.js 的 EventEmitter
可以用于处理异步事件。
6. 第三方库
可以使用第三方库(如 async
)来简化异步操作。
请求拦截器 响应拦截器 干了什么
在前端开发中,请求拦截器 和响应拦截器 是用于在发送请求和接收响应时进行统一处理的机制。它们通常用于封装 HTTP 请求库(如 axios
或 fetch
),以便在请求发出前或响应返回后执行一些通用的逻辑。
1. 请求拦截器(Request Interceptor)
请求拦截器用于在请求发出之前对请求进行统一处理。常见的用途包括:
- 添加请求头(如
Authorization
令牌)。 - 修改请求数据(如格式化参数)。
- 显示加载状态(如显示 Loading 动画)。
- 取消请求(如根据条件中断请求)。
常见场景:
-
添加认证信息:
javascriptconfig.headers['Authorization'] = 'Bearer token';
-
格式化请求数据:
javascriptif (config.data) { config.data = JSON.stringify(config.data); }
-
取消请求:
javascriptif (shouldCancelRequest(config)) { return Promise.reject({ message: '请求被取消' }); }
2. 响应拦截器(Response Interceptor)
响应拦截器用于在接收到响应之后对响应进行统一处理。常见的用途包括:
- 统一处理错误(如 HTTP 状态码非 200 的情况)。
- 格式化响应数据(如提取
data
字段)。 - 隐藏加载状态(如隐藏 Loading 动画)。
- 缓存响应数据。
常见场景:
-
统一处理错误:
javascriptif (error.response.status === 401) { redirectToLogin(); }
-
格式化响应数据:
javascriptreturn response.data;
-
缓存响应数据:
javascriptif (shouldCache(response)) { cache.set(response.config.url, response.data); }
3. 请求拦截器和响应拦截器的工作流程
以下是请求拦截器和响应拦截器的工作流程:
-
请求发出前:
- 请求拦截器对请求配置进行处理。
- 如果请求拦截器返回
config
,请求会继续发出。 - 如果请求拦截器返回
Promise.reject
,请求会被中断。
-
请求发出后:
- 服务器返回响应。
- 响应拦截器对响应数据进行处理。
- 如果响应拦截器返回
response
,响应数据会传递给业务代码。 - 如果响应拦截器返回
Promise.reject
,错误会传递给业务代码。
4. 总结
- 请求拦截器:用于在请求发出前对请求进行统一处理,如添加请求头、显示 Loading 状态等。
- 响应拦截器:用于在接收到响应后对响应进行统一处理,如格式化数据、隐藏 Loading 状态、统一处理错误等。
tailwindcss 是什么?
Tailwind CSS 是一个功能优先的 CSS 框架,提供了大量低级别的实用类,允许开发者直接在 HTML 中通过组合这些类来构建用户界面。与传统的 CSS 框架不同,Tailwind 不提供预定义的组件,而是通过实用类实现高度定制化的设计,同时支持响应式布局、状态变体和 JIT 模式,大幅提升开发效率和性能。
Tailwind CSS 的核心优势在于其灵活性和一致性。开发者可以通过配置文件自定义设计系统,确保项目样式统一,同时避免编写重复的 CSS 代码。尽管学习曲线较陡,且可能导致 HTML 代码臃肿,但 Tailwind CSS 特别适合快速原型开发、定制化设计以及中小型项目。
数组常用的方法?
1. 修改数组的方法
这些方法会直接修改原数组。
-
(1)
push()
:在数组末尾添加一个或多个元素。 -
(2)
pop()
:删除数组的最后一个元素。 -
(3)
unshift()
:在数组开头添加一个或多个元素。 -
(4)
shift()
:删除数组的第一个元素。 -
(5)
splice()
:在指定位置添加或删除元素。javascriptconst arr = [1, 2, 3]; arr.splice(1, 1, 4); // 从索引 1 开始删除 1 个元素并插入 4,arr 变为 [1, 4, 3]
-
(6)
reverse()
:反转数组的顺序。 -
(7)
sort()
:对数组元素进行排序。javascriptconst arr = [3, 1, 2]; arr.sort(); // arr 变为 [1, 2, 3]
2. 不修改原数组的方法
这些方法不会修改原数组,而是返回一个新数组或值。
-
(1)
concat()
:合并两个或多个数组。 -
(2)
slice()
:提取数组的一部分。javascriptconst arr = [1, 2, 3, 4]; const newArr = arr.slice(1, 3); // newArr 为 [2, 3]
-
(3)
join()
:将数组元素连接成一个字符串。 -
(4)
indexOf()
:查找指定元素的第一个索引。javascriptconst arr = [1, 2, 3]; const index = arr.indexOf(2); // index 为 1
-
(5)
lastIndexOf()
:查找指定元素的最后一个索引。javascriptconst arr = [1, 2, 3, 2]; const index = arr.lastIndexOf(2); // index 为 3
-
(6)
includes()
:判断数组是否包含某个元素。
3. 遍历数组的方法
这些方法用于遍历数组元素。
-
(1)
forEach()
:对数组的每个元素执行一次函数。javascriptconst arr = [1, 2, 3]; arr.forEach(item => console.log(item)); // 依次输出 1, 2, 3
-
(2)
map()
:对数组的每个元素执行一次函数,并返回新数组。javascriptconst arr = [1, 2, 3]; const newArr = arr.map(item => item * 2); // newArr 为 [2, 4, 6]
-
(3)
filter()
:过滤数组,返回满足条件的元素组成的新数组。javascriptconst arr = [1, 2, 3]; const newArr = arr.filter(item => item > 1); // newArr 为 [2, 3]
-
(4)
reduce()
:对数组元素执行累加器函数,返回一个累加结果。javascriptconst arr = [1, 2, 3]; const sum = arr.reduce((acc, item) => acc + item, 0); // sum 为 6
-
(5)
some()
:判断数组中是否有元素满足条件。javascriptconst arr = [1, 2, 3]; const hasEven = arr.some(item => item % 2 === 0); // hasEven 为 true
-
(6)
every()
:判断数组中的所有元素是否都满足条件。javascriptconst arr = [1, 2, 3]; const allEven = arr.every(item => item % 2 === 0); // allEven 为 false
4. 其他常用方法
-
(1)
find()
:查找数组中第一个满足条件的元素。javascriptconst arr = [1, 2, 3]; const result = arr.find(item => item > 1); // result 为 2
-
(2)
findIndex()
:查找数组中第一个满足条件的元素的索引。 -
(3)
flat()
:将嵌套数组扁平化。javascriptconst arr = [1, [2, [3]]]; const newArr = arr.flat(2); // newArr 为 [1, 2, 3]
-
(4)
flatMap()
:先对数组元素执行map()
,然后对结果执行flat(1)
。javascriptconst arr = [1, 2, 3]; const newArr = arr.flatMap(item => [item, item * 2]); // newArr 为 [1, 2, 2, 4, 3, 6]
字符串上有什么方法?
1. 查找和截取字符串
-
(1)
charAt()
:返回指定索引位置的字符。javascriptconst str = "Hello"; console.log(str.charAt(1)); // 'e'
-
(2)
charCodeAt()
:返回指定索引位置字符的 Unicode 编码。 -
(3)
indexOf()
:返回指定字符串第一次出现的索引。javascriptconst str = "Hello"; console.log(str.indexOf('l')); // 2
-
(4)
lastIndexOf()
:返回指定字符串最后一次出现的索引。 -
(5)
includes()
:判断字符串是否包含指定子字符串。 -
(6)
startsWith()
:判断字符串是否以指定子字符串开头。 -
(7)
endsWith()
:判断字符串是否以指定子字符串结尾。 -
(8)
slice()
:提取字符串的一部分。javascriptconst str = "Hello"; console.log(str.slice(1, 3)); // 'el'
-
(9)
substring()
:提取字符串的一部分(与slice()
类似,但不支持负数索引)。javascriptconst str = "Hello"; console.log(str.substring(1, 3)); // 'el'
2. 修改字符串
-
(1)
toUpperCase()
:将字符串转换为大写。javascriptconst str = "Hello"; console.log(str.toUpperCase()); // 'HELLO'
-
(2)
toLowerCase()
:将字符串转换为小写。 -
(3)
trim()
:去除字符串两端的空白字符。javascriptconst str = " Hello "; console.log(str.trim()); // 'Hello'
-
(4)
trimStart()
/trimLeft()
:去除字符串开头的空白字符。 -
(5)
trimEnd()
/trimRight()
:去除字符串结尾的空白字符。 -
(6)
replace()
:替换字符串中的指定子字符串。javascriptconst str = "Hello"; console.log(str.replace('He', 'Ha')); // 'Hallo'
-
(7)
replaceAll()
:替换字符串中所有匹配的子字符串。
3. 分割和连接字符串
-
(1)
split()
:将字符串按指定分隔符分割成数组。javascriptconst str = "Hello,World"; console.log(str.split(',')); // ['Hello', 'World']
-
(2)
concat()
:连接多个字符串。
4. 其他常用方法
-
(1)
repeat()
:将字符串重复指定次数。javascriptconst str = "Hello"; console.log(str.repeat(2)); // 'HelloHello'
-
(2)
padStart()
:在字符串开头填充指定字符,直到字符串达到指定长度。javascriptconst str = "Hello"; console.log(str.padStart(10, '*')); // '*****Hello'
-
(3)
padEnd()
:在字符串结尾填充指定字符,直到字符串达到指定长度。 -
(4)
match()
:返回字符串中匹配正则表达式的结果。javascriptconst str = "Hello"; console.log(str.match(/l/g)); // ['l', 'l']
-
(5)
search()
:返回字符串中匹配正则表达式的第一个索引。javascriptconst str = "Hello"; console.log(str.search(/l/)); // 2 ```**
结语
通过这次分享,希望能让你对春招面试有了更清晰的认识和准备。