【我的面试笔记】判断对象是否存在“环”+手写一个useLocalStorage

287 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

前言 :哈喽大家好我是一泽,回忆起6月份面试的时候遇到过这两道题,现在想重新整理一下

需求一: 检查对象是否存在环

  • 思路:存在环的意思是对象的某个子节点属性赋值了父节点的引用,形成了一个链式循环,我们可以使用递归和JSON.stringify()两种方法来实现

    1.利用JSON.stringify()方法,如果对象形成死循环,就会抛出异常

    const hasCycle= obj=> {
      let res = false
      try {
          JSON.stringify(obj)
      } catch (e) {
          res = true  //如果抛出异常,说明有环
      } finally {
          return res
      }
    }
    
    

    2.递归法

    const hasCycle = (obj, cache = []) => {
    let res = false;
    for (let k in obj) {
      if (typeof obj[k] === "object" && obj[k] != null) {
        if (cache.indexOf(obj[k]) !== -1) {   
          res = true;  //缓存数组中如果存在这个属性值,说明某个子节点被赋值了父节点的引用
          break;
        } else {
          cache.push(obj[k]);
          res = hasCycle(obj[k], cache);
          if (res) {
            break;
           }
          cache.pop(); //因为递归返回,后面遍历的属性不是这个数据的子属性,所以需要把数据推出来
         }
       }
     }
     return res
    }
    

需求二: 手写一个useLocalStorage

  • 思路:localStorage的基本用法就是 localStorage.getItem()和 localStorage.setItem(),在不同的组件去获取和更新。那么我们就能推断,如果将其单独封装成hook,那么每次使用其实就相当于获取、更新它的state
      import * as React, { useEffect, useState } from 'react';
      
      const useLocalStorage = (key, initialValue) => {
      if (typeof key !== 'string') {
          throw new Error('key一定要传字符串!');
        }
      const [value, setValue] = useState( ()=>{
              try {
                  const currentVal = localStorage.getItem(key);
                  return currentVal ? JSON.parse(currentVal) : initialValue;
              } 
              catch (e) {
                  return initialValue;
              }
        } );
    
        useEffect(() => {
          localStorage.setItem(key, JSON.stringify(value));
        }, [value, key]);
    
        return [value, setValue];
      };