使用 JSON.parse(JSON.stringify()) 深拷贝时需要注意不能拷贝循环引用属性和函数属性。
浅拷贝:只是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据
function shallowCopy(obj){
var data = {};
for (var i in obj){
if(obj.hasOwnProperty(i)){ // for in 循环,也会循环原型链上的属性,所以这里需要判断一下
//hasOwnProperty的相关知识点,查看下面的:相关知识点补充
data[i] = obj[i]
}
}
return data
}
深拷贝:将数据中所有的数据拷贝下来,对拷贝之后的数据进行修改不会影响到原数据
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj; // 非对象类型直接返回
}
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]); // 递归拷贝对象的每个属性值
}
}
return copy;
}
防抖:n 秒后再执行回调,若在 n 秒内被重复触发,则重新计时;防抖的基本思想是在函数被连续调用时,只执行最后一次调用,并在指定的时间间隔内没有新的调用才执行函数。如果在时间间隔内有新的调用,则重新计时。
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效;节流的基本思想是限制函数在一定时间间隔内的执行次数,例如每隔一段时间执行一次,并在该时间间隔内忽略其他的函数调用。
function throttle(func, delay) {
let timer;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
}
};
}
Promise是异步编程的一种解决方案,可以解决传统的回调地狱问题,使得异步代码更加扁平化、可读性更高,避免了多层嵌套的回调函数。
如果第二个Promise执行失败,Promise.all()返回的Promise会立即失败,并把第二个Promise的拒绝原因作为参数传递给失败的回调函数,同时第三个Promise不会被执行。
在 async 函数内部,可以使用 try 关键字来包裹可能抛出异常的代码块。在 await 表达式之后,如果异步操作抛出异常,它将被捕获并传递给 catch 块,然后执行相应的错误处理逻辑。在 catch 块中,可以访问到抛出的异常对象,并进行相应的处理,例如打印错误信息或执行其他错误处理操作。
注意,使用 try/catch 只能捕获到 await 表达式所在的异步函数内部抛出的异常。如果在异步函数之外发生异常,或者在异步函数内部的同步代码中发生异常,try/catch 是无法捕获到的。在这种情况下,可以使用 .catch() 方法来捕获异常,或者在调用异步函数的地方使用 try/catch 来处理异常。
React Hooks 是从 React 16.8 版本引入的。在此版本之前,React 的组件主要是基于类的,使用类组件来管理状态和生命周期方法
使用 Hooks 进行数据通信有多种方式,以下是一些常见的方法:
Props:父组件通过 Props 将数据传递给子组件。子组件可以通过 props 对象获取传递过来的数据,并在组件内部使用。
Context:Context 提供了一种在组件之间共享数据的方法,避免了通过 Props 层层传递数据。通过创建一个 Context 对象,在父组件中将需要共享的数据包裹在 Provider 组件中,子组件可以通过 useContext Hook 或 Consumer 组件来获取共享数据。
useState Hook:useState Hook 可以在函数组件中声明和管理状态。通过调用 useState 返回的状态和更新函数,组件可以在函数组件中维护自己的状态数据。
useReducer Hook:useReducer Hook 是另一种用于状态管理的 Hook。它接受一个 reducer 函数和初始状态作为参数,并返回当前状态和 dispatch 函数。通过 dispatch 函数可以触发 reducer 来更新状态。
Redux 或其他状态管理库:如果需要更复杂的状态管理和数据通信方案,可以使用像 Redux 这样的状态管理库。Redux 提供了统一的状态管理和数据流控制机制,使得组件之间的数据通信更加可预测和可维护。
组件从 被创建 到 被销毁 的过程称为组件的生命周期。
组件的生命周期可分成三个状态:
组件的生命周期可分为三个阶段:
Webpack是一个现代化的静态模块打包工具,它主要用于构建和打包前端项目
1. babel-loader:将ES6+的JavaScript代码转换为可以在旧版本浏览器中运行的JavaScript代码。
2. css-loader:处理CSS文件,使其能够被Webpack打包。
3. file-loader:处理文件,例如图片和字体文件,将其复制到输出目录,并返回文件路径。
4. style-loader:将CSS代码注入到页面的<style>标签中。
Loader可以通过在Webpack配置文件中的module.rules中进行配置。每个规则对象都包含了一个test属性,用于匹配需要处理的文件类型,以及一个use属性,用于指定使用的Loader。
1. HtmlWebpackPlugin:生成HTML文件,并将Webpack打包后的文件自动引入到HTML中。
2. MiniCssExtractPlugin:将CSS提取为单独的文件,而不是注入到页面的<style>标签中。
3. OptimizeCSSAssetsPlugin:优化CSS输出,例如压缩和去重。
4. CleanWebpackPlugin:在每次构建之前清理输出目录。
1. 入口点拆包:将应用程序的不同部分拆分成多个入口点,每个入口点对应一个输出文件。
2. 动态导入:使用ES6的import()语法实现按需加载。
3. SplitChunks Plugin:通过配置optimization.splitChunks选项,
将公共模块拆分到单独的文件中。
事件循环(Event Loop)是 JavaScript 运行时环境(如浏览器或 Node.js)用来处理异步操作的机制。它负责管理 JavaScript 代码的执行顺序,使得异步操作能够以非阻塞的方式进行。
事件循环的主要思想是将任务分为不同的队列,然后按照特定的规则来执行这些队列中的任务。在浏览器环境中,事件循环由浏览器的主线程控制,而在 Node.js 环境中,则由 Node.js 的事件驱动模型管理。
下面是事件循环的基本步骤:
执行同步任务:从调用栈(执行上下文栈)中取出位于栈顶的同步任务执行。
执行微任务(Microtask)队列:在执行同步任务过程中,如果遇到微任务(如 Promise 的回调函数、queueMicrotask 方法等),则将其添加到微任务队列中。
执行宏任务(Macrotask)队列:当同步任务和微任务队列都为空时,事件循环会从宏任务队列中取出一个任务执行。常见的宏任务包括 setTimeout、setInterval、requestAnimationFrame、I/O 操作等。
更新渲染:在浏览器环境中,如果当前任务完成后需要更新页面的渲染,会执行渲染操作。
重复上述步骤:事件循环会不断重复执行上述步骤,直到所有任务都被处理完毕。
单点登录(Single Sign-On,简称 SSO)是一种身份验证和授权机制,允许用户使用一组凭据(如用户名和密码)来访问多个相关系统或应用,而不需要在每个系统中重新进行身份验证。
在单点登录流程中,用户只需要登录一次,然后就可以访问与该身份验证机制集成的多个应用或系统,而无需在每个应用中单独进行登录。这提供了更方便的用户体验,并减少了用户需要记住多个账号和密码的负担。
要判断用户是否登录,可以使用以下方法:
微前端(Micro Frontends)是一种架构风格,旨在将前端应用程序拆分为更小、更可管理的部分,每个部分都是独立的子应用。这些子应用可以独立开发、部署和扩展,并可以通过统一的容器应用程序来组合在一起。微前端的目标是提高前端开发的灵活性、可维护性和可扩展性,同时支持团队间的独立开发和快速交付。
微前端的主要概念包括:
低代码(Low-Code)是一种应用开发方法,旨在通过使用可视化界面、拖放组件和少量的手写代码来加速应用程序的开发过程。低代码平台提供了一系列可配置的组件和预定义的业务逻辑,开发人员可以通过配置和定制来创建应用程序,而不是从头开始编写所有代码。
低代码的主要特点包括:
webpack 的运行流程是一个串行的过程,它的工作流程就是将各个插件串联起来
从启动到结束会依次执行以下三大步骤: