83. ES6 中的 let 和 const
- let 和 const 的区别是什么?
-
let 和 const 是 ES6 引入的用于声明变量的新方式,相比于传统的 var,它们具有以下特性:
- 块级作用域:
let
和const
声明的变量在其所在的块级作用域内有效,不会在作用域外被访问到。 - 变量提升不同:虽然 let 和 const 也有变量提升,但在提升过程中,声明的变量不会初始化,因此在声明前使用会抛出
ReferenceError
,这被称为 暂时性死区 (Temporal Dead Zone)。 - 不可重复声明:在同一作用域内,不能使用 let 或 const 重复声明同名变量。
- const 用于声明常量,必须在声明时初始化,且不能重新赋值,但对象和数组的属性可以改变。
- 块级作用域:
-
示例:
// let 的块级作用域 if (true) { let x = 10; console.log(x); // 10 } console.log(x); // ReferenceError: x is not defined // const 的不可变性 const y = 20; y = 30; // TypeError: Assignment to constant variable. // const 对象的属性可修改 const obj = { name: 'Alice' }; obj.name = 'Bob'; // 合法 console.log(obj.name); // 'Bob'
-
84. Promise 工作原理
-
Promise 是什么?
-
Promise 是用于处理异步操作的对象,它代表一个将来可能完成或失败的操作及其结果。Promise 有三种状态:
- Pending(进行中):初始状态,操作尚未完成。
- Fulfilled(已成功):操作成功完成。
- Rejected(已失败):操作失败。
-
Promise 的基本用法:
const promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('成功'); }, 1000); }); promise.then((result) => { console.log(result); // '成功' }).catch((error) => { console.log(error); });
-
-
Promise.all 和 Promise.race 的区别?
-
Promise.all:接受一个包含多个 Promise 的数组,只有当所有 Promise 都成功时,它才会
resolve
,如果其中一个 Promise 失败,它就会reject
。- 示例:
const p1 = Promise.resolve('成功1'); const p2 = Promise.resolve('成功2'); const p3 = Promise.reject('失败'); Promise.all([p1, p2, p3]) .then((results) => { console.log(results); }) .catch((error) => { console.log(error); // '失败' });
- 示例:
-
Promise.race:也是接受一个包含多个 Promise 的数组,但只要有一个 Promise 完成(无论是
resolve
还是reject
),它就会返回那个 Promise 的结果。- 示例:
const p1 = new Promise((resolve) => setTimeout(resolve, 500, '成功1')); const p2 = new Promise((resolve) => setTimeout(resolve, 100, '成功2')); Promise.race([p1, p2]).then((result) => { console.log(result); // '成功2' });
- 示例:
-
85. React 生命周期
-
React 的生命周期有哪些?
React 的组件生命周期分为三个阶段:挂载阶段、更新阶段 和 卸载阶段。-
挂载阶段 (Mounting):
- 当组件被创建并插入 DOM 时会触发以下钩子函数:
constructor()
:用于初始化状态和绑定方法。componentDidMount()
:在组件挂载后执行,通常用于发送网络请求或操作 DOM。
- 当组件被创建并插入 DOM 时会触发以下钩子函数:
-
更新阶段 (Updating):
- 当组件的 props 或 state 发生变化时会触发:
shouldComponentUpdate(nextProps, nextState)
:用于判断是否需要重新渲染组件,返回true
则重新渲染,返回false
则跳过。componentDidUpdate(prevProps, prevState)
:在更新完成后执行,通常用于 DOM 操作或发起依赖于更新的数据请求。
- 当组件的 props 或 state 发生变化时会触发:
-
卸载阶段 (Unmounting):
- 当组件即将被移除时,会调用
componentWillUnmount()
,通常用于清理定时器、取消网络请求等操作。
- 当组件即将被移除时,会调用
- 示例:
class MyComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } componentDidMount() { console.log('组件已挂载'); } componentDidUpdate(prevProps, prevState) { console.log('组件已更新'); } componentWillUnmount() { console.log('组件即将卸载'); } render() { return <div>{this.state.count}</div>; } }
-
86. Vue 生命周期
-
Vue 的生命周期有哪些?
Vue 的生命周期同样分为 创建阶段、挂载阶段、更新阶段 和 销毁阶段,并提供相应的钩子函数:-
创建阶段:
beforeCreate()
:实例初始化之后,数据观测和事件配置之前。created()
:实例已经创建完成,数据观测和事件配置已经完成,但 DOM 尚未挂载。
-
挂载阶段:
beforeMount()
:在挂载之前被调用,此时模板编译完成,但尚未插入 DOM。mounted()
:在组件挂载到 DOM 后调用,通常用于 DOM 操作或 AJAX 请求。
-
更新阶段:
beforeUpdate()
:当数据更新时调用,但在虚拟 DOM 重新渲染和打补丁之前。updated()
:组件更新完毕后调用。
-
销毁阶段:
beforeDestroy()
:实例销毁之前调用,可以在此清理事件监听器等。destroyed()
:实例销毁后调用,所有绑定的事件和数据观察者都会移除。
- 示例:
new Vue({ data() { return { message: 'Hello Vue' }; }, beforeCreate() { console.log('beforeCreate'); }, created() { console.log('created'); }, beforeMount() { console.log('beforeMount'); }, mounted() { console.log('mounted'); }, beforeUpdate() { console.log('beforeUpdate'); }, updated() { console.log('updated'); }, beforeDestroy() { console.log('beforeDestroy'); }, destroyed() { console.log('destroyed'); } });
-
87. 深拷贝和浅拷贝
- 什么是深拷贝和浅拷贝?
-
浅拷贝:只复制对象的引用,而不是复制对象本身。如果拷贝后的对象发生改变,原对象也会受到影响。
- 常见浅拷贝的方法:
Object.assign()
、Array.slice()
。 - 示例:
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = Object.assign({}, obj1); obj2.b.c = 3; console.log(obj1.b.c); // 3,原对象的 b 也被修改了
- 常见浅拷贝的方法:
-
深拷贝:完全复制一个新的对象,修改拷贝后的对象不会影响原对象。
- 常见深拷贝的方法:
JSON.parse(JSON.stringify())
(但不支持函数和 undefined)。 - 示例:
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = JSON.parse(JSON.stringify(obj1)); obj2.b.c = 3; console.log(obj1.b.c); // 2,原对象不受影响
- 常见深拷贝的方法:
-
88. 冒泡排序
-
冒泡排序是什么?
冒泡排序 是一种简单的排序算法,它通过重复遍历待排序的列表,相邻元素两两比较并交换,最终将最大或最小的元素“冒泡”到列表的一端。 -
冒泡排序的时间复杂度:
O(n^2)
,适用于小规模数据
排序。
- 示例:
function bubbleSort(arr) { const len = arr.length; for (let i = 0; i < len; i++) { for (let j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 交换 } } } return arr; } console.log(bubbleSort([5, 3, 8, 4, 2])); // [2, 3, 4, 5, 8]