面试专题:settimeout剩余参数,数组扁平化,var实现let,性能优化Memo,useMemo,useCallback

面试专题:settimeout剩余参数,数组扁平化,var实现let,性能优化Memo,useMemo,useCallback

1.settimeout剩余参数:如何用settimeout去实现setinterval的功能

  • 大多数小伙伴遇到这种编程题,第一反应就是惊喜,so easy,于是乎,就嗖嗖嗖写完了
function setInterval_(callback,time) {
     function settimeout (){
         setTimeout(()=>{
             callback()
             settimeout()
         },time)
     }
     settimeout()
};
setInterval_(()=>{
     console.log(1);
},1000)
  • 看起来功能都实现了,但是仅仅是这个简单吗?答案是不,setinterval不止2个参数!
  • var intervalID = setInterval(func, [delay, arg1, arg2, ...]);
  • 看的出来,不止2个参数,甚至有无数参数
  • 这些参数都会作为回调的入参传穿进去
	function setInterval_(callback,time,...args) {
	     let callback_ = callback;
	     function settimeout (){
	         setTimeout((...args_)=>{
	             callback_(...args_);
	             settimeout()
	         },time,...args)
	     }
	     settimeout()
	};
	setInterval_((...args)=>{
	     console.log(1,...args);
	},11,22,33)

2.数组扁平化:设计一个flat函数将如下数组arr=[1,2,[‘3’,4,‘5’,[6,[7,8],9]]]输出为1,2,‘3’,4,‘5’,6,7,8,9。写出两种方法,要求不改原初始类型

1. 常规循环和递归
function glats(a) {
     let flatArr = [];
    function flat(ele) {
        if (Array.isArray(ele)) {
            ele.forEach((item) => {
                if (Array.isArray(item)) {
                    flat(item)
                } else {
                    flatArr.push(item)
                }
            })
        } else {
            flatArr.push(ele)
        }
    }
    flat(a)
    return flatArr
}
2.ES6新特性flat()
  • flat可以对数组进行扁平化
  • 利用递归不断扁平化
  • 利用try catch 实现跳出foreach循环
function myFlat(a) {
    let flatArr = []
    function flat(ele) {
        flatArr = ele.flat(1); // 扁平化一层
        try {
            flatArr.forEach(item => {
            if (Array.isArray(item)) {
                flat(flatArr) // 递归
                throw new Error() // 利用catch跳出循环
            }
        })
        } catch (error) {}
    }
    flat(a);
    return flatArr
}

3.常用的 ES6 语法有哪些,var 怎么实现let

  • let 相对于var来说形成了块级作用域
for (let i = 0; i < 4; i++) {
           setTimeout(()=>{
                console.log(i); // 0 1 2 3
           },100)        
       }
 for (var c = 0; c < 4; i++) {
     setTimeout(()=>{
          console.log(c); // 4 4 4 4
     },100)        
 }
  • let 的块级作用域只会在当前作用域生效,超出则回收,而var并不会被回收
for (var c = 0; c < 4; c++) {}
console.log(c) // 4
for (let i = 0; i < 4; i++) {};
console.log(i) // undefined

  • 利用函数的闭包存储当前var的值
for (var i = 0; i < 4; i++) {
    function va(i){
        setTimeout(()=>{
             console.log(i); //0 1 2 3
        },1000)
    }
    va(i)
}

4.useCallback和useMemo有什么区别

1.前世:class组件大一统时代
  • 说起性能优化,我们一定不会陌生。一个是pureComponent,一个是shouldComponentUpdate
  • shouldComponentUpdate:根据返回值来处理是否要更新
  • pureComponent:包裹在组件外面,根据shouldComponentUpdate进行封装的,对props进行浅层的对比,从而判断是否需要更新
import React, { Component } from 'react';

function shallowEqual(obj1, obj2) {//传入新老state和prop
  if (obj1 === obj2) {//一样直接不改变
    return true
  }
  if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
    return false//检测,如果有一个满足就更新
  }
  let keys1 = Object.keys(obj1)//拿到所有属性名组成的数组
  let keys2 = Object.keys(obj2)//拿到所有属性名组成的数组
  if (keys1.length !== keys2.length) {
    return false//如果键值对数量不相等,那么更新
  }
  for (const key of keys1) {//循环进行比较
    if (!obj2.hasOwnProperty(key) || obj1[key] !== obj2[key]) {
      return false//如果obj2没有key的值,或者表层的key的值不相等时,更新
    }
  }
  return true//走到这里,说明没改变,那么不更新
}

class PureComponent extends Component {//引用shouldcomponentupdate方法
  shouldComponentUpdate(nextProps, nextState) {//传入的nextprops,nextState与这次的比较,并且传入
    return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
    //返回值是ture就更新组件,false就不更新组件,这里调用手写shallowEqual方法
  }
  render() {
    return this.props.children;
  }
}
export default PureComponent;
2.今生:函数式轻量化组件,hooks百花齐放

React.memo():解决了整个组件的是否render的问题(实现了类似PureComponent)

  • 第二个参数回调如果没传的话,就会进行浅对比,
function MyComponents() {};
function areEqual(prevState, nextState) {
    /*
    return true if passing nextProps to render would return
     the same result as passing prevProps to render,
    otherwise return false
    */  
}
export default React.memo(MyComponents,areEqual)

React.useMemo()细粒度性能优化,返回的是一个memoized值,当依赖项变化时才会重新计算

  • usememo是在render期间执行的,所以不能进行一些副操作,如网络请求
  • 如果没有提供依赖值,那么每次都会重新计算
const useMomes =useMemo(()=>{
	return a+b+c
},[a,b]);

React.useCallback:用法其实和useMemo是一样的,但是他们唯一的区别是,useCallback是缓存了函数

  • 父子关系组件中,父组件向子组件传递一个方法,由有函数的特殊性,每次父组件更新都会触发子组件,此时用usecallback,即可指定值变化时触发更新.
const fnB=()=>{}
const fnA = useCallback(fnB, [a])
3.速记口诀:值是useMemo,函数是useCallback,都不传Memo
  • 只穿值的话,优化用useMomo,因为会对值进行浅different
  • 函数则用useCallback,因为他会缓存返回值的空间地址。
  • 既没有值也没有函数时,可以用Memo
  • 三兄弟可以认为是不同阶段的不同分支和方向,都会用闭包去缓存值,他们反映的都是当前的状态
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

家雀安知鸿鹄志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值