一、作用域是什么?
1、编译器、引擎之间的关系?
针对代码段 var a = 2
编译器首先将这段程序分解为 词法单元 ,然后将 词法单元 解析成一个 树结构 ,也叫 AST(Abstract Syntax Tree) ;
变量的赋值操作会执行两个动作:
- 编译器在当前作用域中声明一个变量(如果之前没有声明过)
- 运行时,引擎会在作用域中查找该变量,如果找到就会对它赋值。
二、节流防抖?
let timerGap = 0;
let timer = null;
const handleSearch = (searchContent) => {
const curTime = Date.now();
if (curTime - timerGap < 500) {
clearTimeout(timer);
}
timerGap = Date.now();
timer = setTimeout(() => {
onSubmit(searchContent);
}, 500)
}
三、try / catch / finally
finally将始终在控制流退出try...catch....finally...
构造之前执行;
finally总是执行,无论是否抛出异常
结构可以是: try...catch...
, try...finally...
, try...catch...finally...
try {
tryStatements
} catch (error) {
catchStatements
} finally {
finallyStatements
}
四、useMemo && memo
1.useMemo
当a1
, a2
发生变化时,执行useMeno
中的函数,写法和useEffect
一样
const renderMenu = useMeno(() => {
return ()
}, [a1, a2]);
为什么要使用useMemo呢?
父组件将一个值传递给子组件,父组件的其他值发生变化时,子组件也会跟着渲染多次,会造成性能浪费;useMemo
可以将父组件传递给子组件的值缓存
起来,只有当useMemo
中的第二个参数状态变化时,子组件才重新渲染。
useMemo
可用于缓存函数的执行结果,仅当依赖项发生变化时才会重新计算。
2.memo
const Parent = () => {
const [text, setText] = useState('');
......
<Child name={text} />
}
⚠️ 父组件name属性或text属性变化都会导致Parent函数重新执行,即使传入子组件的props没有任何变化,甚至子组件没有依赖任何props属性,都会导致子组件重新渲染
。
使用memo包裹子组件
时,只有props发生改变,子组件才会重新渲染
,以提升一定的性能。
import React, { memo } from 'react';
const Child = memo((props: any) => {
return (
<div>...</div>
)
});
3.useEffect 和 useMemo 的区别
- useEffect是在
DOM改变之后触发
,useMemo在DOM渲染之前就触发
;