你不知道的JS(从原理出发)

140 阅读2分钟

异步函数

一、作用域是什么?

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渲染之前就触发;