个人面经考点记录

395 阅读4分钟

1. es6中的set有顺序吗

无重复值的有序列表,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用。

2. React事件绑定

并不是将合成事件直接绑定在dom上面,而是采用`事件冒泡`的形式冒泡到`document`上面,
https://juejin.cn/post/6988450132928757768/  
但在React v17 中,React 不会再将事件处理添加到 document 上,而是将事件处理添加到渲染 React 树的根 DOM 容器中

3. diff算法

diff算法的核心是对树进行分层比较,并且只对两棵树的同层进行比较。React会对新旧两棵树进行一个深度优先的遍历,每遍历到一个节点就把该节点和新的树进行对比。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。这样只需要对树进行一次遍历,便能完成整个DOM树的比较。

4. 函数防抖节流的应用场景

防抖:在事件触发n秒后执行函数,如果在n秒内再次出发,重新计时  
节流:当多次执行某一动作,每个一段时间,只执行一次函数。
##### 函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:

搜索框搜索输入。只需用户最后一次输入完,再发送请求\
手机号、邮箱验证输入检测(change、input、blur、keyup等事件触发,每次键入都会触发)\
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。\
鼠标的mousemove、mouseover\
导航条上,用户不停的在导航区域滑动

##### 函数节流的应用场景
间隔一段时间执行一次回调的场景有:  

滚动加载,加载更多或滚到底部监听,window.onscroll和滑到底部自动加载更多\
谷歌搜索框,搜索联想功能\
高频点击提交,表单重复提交
> Lodash  
> _.debounce(func, [wait=0], [options=])\
> _.throttle(func, [wait=0], [options=])

5. js实现简单的正方形向右移动动画效果

使用递归函数和setTimeout解决
    
    var odiv=document.getElementsByTagName('div')[0]
    var left = 0
    function fun () {
        if(odiv.style.left > 200){
            return
        }
        setTimeout(()=>{
            left += 1
            odiv.style.left = left + 'px'
            fun()
        },100)
    }
    
    fun()

6. 怎么避免内存泄露

1. 意外的全局变量:启用严格模式解析 JavaScript ,避免意外的全局变量。  
2. 被遗忘的计时器或回调函数: clearInterval
3. 脱离 DOM 的引用  
4. 闭包:
    -  在退出函数之前,将不使用的局部变量全部删除。可以使变量赋值为null  
    -  避免变量的循环赋值和引用

7. React+Redux之connect用法介绍及原理解析

> connect真正连接 Redux 和 React,它包在我们的容器组件的外一层,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件。
> -   在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
> -   接收Redux的store作为props,通过context对象传递给子孙组件上的connect

connect是一个高阶函数,首先传入mapStateToProps、mapDispatchToProps,然后返回一个生产Component的函数(wrapWithConnect),然后再将真正的Component作为参数传入wrapWithConnect,这样就生产出一个经过包裹的Connect组件.

```
export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
  return function wrapWithConnect(WrappedComponent) {
    class Connect extends Component {
      constructor(props, context) {
        // 从祖先Component处获得store
        this.store = props.store || context.store
        this.stateProps = computeStateProps(this.store, props)
        this.dispatchProps = computeDispatchProps(this.store, props)
        this.state = { storeState: null }
        // 对stateProps、dispatchProps、parentProps进行合并
        this.updateState()
      }
      shouldComponentUpdate(nextProps, nextState) {
        // 进行判断,当数据发生改变时,Component重新渲染
        if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
          this.updateState(nextProps)
            return true
          }
        }
        componentDidMount() {
          // 改变Component的state
          this.store.subscribe(() = {
            this.setState({
              storeState: this.store.getState()
            })
          })
        }
        render() {
          // 生成包裹组件Connect
          return (
            <WrappedComponent {...this.nextState} />
          )
        }
      }
      Connect.contextTypes = {
        store: storeShape
      }
      return Connect;
    }
  }
```
https://www.jianshu.com/p/4af924709b35

8. 浏览器的主要进程和职责

  • 主进程 Browser进程
  • 第三方插件进程
  • GPU 进程
  • 渲染进程

渲染进程 (浏览器内核):

9. HTTP3.0中为什么使用UDP

HTTP3.0弃用TCP协议,改为使用基于UDP协议的QUIC协议来实现。

image.png blog.csdn.net/lisheng1987…