携手创作,共同成长!这是我参与「掘金日新计划 · 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]; };