serendipityApe / javascriptPromotion

资深前端必备的编码问题
3 stars 0 forks source link

实现Immutability helper #14

Open serendipityApe opened 2 years ago

serendipityApe commented 2 years ago

题目 实现 Immutability helper

例子

如果你使用React,你肯定会遇到想要修改state的一部分的情况。

比如下面的state。

const state = {
  a: {
    b: {
      c: 1
    }
  },
  d: 2
}

如果我们想要修改d来生成一个新的state,我们可以用 _.cloneDeep,但是这样没必要因为state.a并不需要被clone。

一个更好的办法是如下的浅拷贝

const newState = {
  ...state,
  d: 3
}

但是又有了新问题,如果我们同时需要修改c的话,我们需要写很复杂的代码,比如:

const newState = {
  ...state,
  a: {
    ...state.a,
    b: {
       ...state.b,
       c: 2
    }
  }
}

这显然还不如cloneDeep。

Immutability Helper 可以很好的解决这个问题。

请实现你自己的Immutability helper update(),需要支持如下调用

  1. {$push: array} 添加元素到数组
    const arr = [1, 2, 3, 4]
    const newArr = update(arr, {$push: [5, 6]})
    // [1, 2, 3, 4, 5, 6]
  2. {$set: any} 修改目标
    
    const state = {
    a: {
    b: {
      c: 1
    }
    },
    d: 2
    }

const newState = update( state, {a: {b: { c: {$set: 3}}}} ) / { a: { b: { c: 3 } }, d: 2 } /

注意我们可以通过$set来修改数组中的元素

const arr = [1, 2, 3, 4] const newArr = update( arr, {0: {$set: 0}} ) // [0, 2, 3, 4]

3. {$merge: object} 合并到目标object

const state = { a: { b: { c: 1 } }, d: 2 }

const newState = update( state, {a: {b: { $merge: {e: 5}}}} ) / { a: { b: { c: 1, e: 5 } }, d: 2 } /

4. {$apply: function} 自定义修改

const arr = [1, 2, 3, 4] const newArr = update(arr, {0: {$apply: (item) => item * 2}}) // [2, 2, 3, 4]


> 答案

/**

serendipityApe commented 2 years ago

明天更,今天忙着面试。。