你的前端技术是否能通过这些高频面试题?(一)https://developer.aliyun.com/article/1426320
7.const, let 和 var 有什么区别
const
、let
和 var
是用于声明变量的关键字,它们有以下区别:
const
:用于声明一个只读的常量,一旦被声明,它的值不能被修改。但是,如果是引用类型(例如对象、数组)时,引用本身是不能被修改的,但对象或数组中的属性或元素是可以修改的。let
:用于声明一个块级作用域的变量,它的作用域仅限于当前的代码块,不会被提升到函数作用域或全局作用域。var
:用于声明一个函数作用域或全局作用域的变量,它的作用域不受代码块的限制,而是在整个函数或全局范围内都可以访问。
下面是一个示例,展示 const
、let
和 var
的差异:
function test() { var a = 10; let b = 20; const c = 30; if (true) { var a = 50; let b = 60; const c = 70; console.log(a, b, c); } console.log(a, b, c); } test(); // 输出:50 60 70,10 20 30
在上面的示例中,使用 var
声明的变量 a
在代码块内部被重新赋值,同时在代码块外部也被重新赋值。这是因为 var
声明的变量的作用域不仅局限于代码块内部,而是在整个函数作用域范围内有效。而使用 let
和 const
声明的变量 b
和 c
只在代码块内部有效,并且代码块内的重新赋值不会影响到代码块外部的变量。
因此,对于变量的声明,应该优先使用 const
和 let
,避免使用 var
。const
用于声明不会被重新赋值的常量(例如数学常数、常量字符串等),使用 let
声明变量并且在需要重新赋值的情况下使用它。如果您需要使用一个变量,但不希望它在函数或全局范围内被访问,请使用 let
。
8.处理 any 类型,如何避免 any
any
是 TypeScript 中的一种通用类型,用于表示任何类型的值。由于它是一种非常宽泛的类型,无法提供静态类型检查的保障,使用 any
类型会增加代码出错的风险,并且对于代码可读性和可维护性也不利。
为了更好地利用 TypeScript 的静态类型检查,应该尽可能避免使用 any
类型。下面是一些方法可以帮助您减少在代码中使用 any
:
- 尽可能地使用具体的类型:在代码中使用具体的类型可以帮助您充分利用 TypeScript 的类型检查功能,这有助于在开发过程中尽早发现潜在的类型转换错误等问题。例如,尽量使用字符串、数字、布尔等具体类型,而不是将它们视为
any
类型。 - 使用泛型:在需要处理多种类型的函数或类时,可以使用泛型来代替
any
。泛型可以帮助您在编译时捕获类型错误,并提高代码的可读性和可维护性。 - 定义接口或类型别名:在需要包含多个属性或方法的复杂结构中,可以使用接口或类型别名来定义类型,而不是使用
any
。使用接口或类型别名可以帮助您充分利用 TypeScript 的类型检查功能,并避免类型转换错误。 - 使用非空断言操作符:在某些情况下,可以使用非空断言操作符
!
来告诉 TypeScript 某个变量不为空,从而避免将其视为any
类型。但是,使用非空断言操作符需要慎重,可能会掩盖真正的类型错误。
总之,尽可能避免使用 any
类型可以帮助您充分利用 TypeScript 的静态类型检查功能,提高代码的可读性和可维护性。在编写代码时,应该尽可能使用具体的类型、泛型、接口等替代方案来代替 any
类型。
9.举几个常用的 Hook,并且解释一下作用
React Hooks 是 React 16.8 版本引入的新功能,当我们需要在函数式组件中使用状态和生命周期方法时,可以使用 Hooks,以下是几个常用的 Hooks。
useState()
useState
Hook 允许函数组件使用状态,这是一个能够重复使用的类似 this.state 和 this.setState 方法的 Hook。useState
为函数组件提供了在不转换为类的情况下存储和更新组件状态和其它变量的能力。
import React, { useState } from 'react'; function Example() { // 声明一个新的状态变量,名为 "count" const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
在上述示例中,useState
的初始值为 0,然后修改 count
的值需要使用 setCount
方法。每次修改了 count
的值,整个组件都会重新渲染。
useEffect()
useEffect
可以用来在函数组件中执行副作用操作,例如获取远程数据、添加或删除 DOM 元素等。useEffect
在每次渲染后执行,但是可以根据需要进行激活和清除。
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // 相当于 componentDidMount 和 componentDidUpdate: useEffect(() => { // 更新文档标题 document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
上述示例中,每次 count
改变,useEffect
执行后会修改文本标题。如果需要进行清除操作,则需要返回一个清除函数:
useEffect(() => { // 执行副作用操作 return () => { // 清除操作 }; });
useContext()
useContext
用于在组件之间共享数据,可以避免使用 props 进行层层传递。通过使用 useContext
,您可以将公共数据从父组件提取并将其传递到子组件中。
import React, { useContext } from 'react'; // 创建一个上下文对象 const MyContext = React.createContext(defaultValue); function ChildComponent() { // 读取 MyContext 的值 const contextValue = useContext(MyContext); return ( <div> {contextValue} </div> ); } function ParentComponent() { // 将值传递给 MyContext return ( <MyContext.Provider value="Hello World!"> <ChildComponent /> </MyContext.Provider> ); }
在上述示例中,将值“Hello World!”传递给 MyContext
,并在 ChildComponent
中使用 const contextValue = useContext(MyContext)
访问该上下文的值。
React Hooks 还有很多其它 Hook,比如 useReducer
、useRef
、useCallback
和 useMemo
等,不同的 Hook 对应不同的用途。在实践中,您可以根据具体需要选择适当的 Hook,避免重复代码和 class 声明。
10.List, Map, Set 有什么区别?
List
、Map
、Set
都是 JavaScript 中常用的数据结构,它们有以下区别:
List
:一组有序的值的集合,类似于数组。你可以通过索引或值来访问列表中的一项。List
具有可变性,可以添加、删除或修改其元素。在 JavaScript 中,可以使用数组(Array
)实现类似List
的数据结构。
// 使用数组实现类似于 List 的数据结构 const list = ['a', 'b', 'c']; list.push('d'); console.log(list); // ['a', 'b', 'c', 'd']
Map
:一组键值对的集合,可以像字典一样使用。每个键都必须是唯一的,而且可以通过键快速查找值。Map
具有可变性,可以添加、删除或修改其键值对。在 JavaScript 中,可以使用对象(Object
)实现类似Map
的数据结构。
// 使用对象实现类似于 Map 的数据结构 const map = { a: 1, b: 2, c: 3 }; map.d = 4; console.log(map); // { a: 1, b: 2, c: 3, d: 4 }
Set
:一组唯一值的集合,不考虑元素的顺序。Set
具有可变性,可以添加或删除其元素。在 JavaScript 中,可以使用数组(Array
)和indexOf()
或者includes()
方法或者对象字面量({}
)实现类似Set
的数据结构。
// 使用数组和 indexOf() 方法实现类似于 Set 的数据结构 const set1 = ['a', 'b', 'c']; if (!set1.includes('d')) { set1.push('d'); } console.log(set1); // ['a', 'b', 'c', 'd'] // 使用对象字面量实现类似于 Set 的数据结构 const set2 = { a: true, b: true, c: true }; set2.d = true; console.log(Object.keys(set2)); // ['a', 'b', 'c', 'd']
综上所述,List
、Map
、Set
的主要区别在于其元素的组织方式和基本操作。List
以有序方式组织元素,随着元素个数增加,查找速度变慢;Map
以键值对的形式组织元素,查找速度较快,但是需要占用更多内存;Set
则是以无序方式组织元素,并保证元素唯一。在实际开发中,应根据要求和场景的不同,选择适合的数据结构。