美文网首页
JavaScript不可变数据

JavaScript不可变数据

作者: JakeBless | 来源:发表于2021-11-05 10:18 被阅读0次

什么是数据不可变

数据一旦创建,就不可更改

immutable对象是不可直接赋值的对象,它可以有效的避免错误赋值的问题

什么是可变数据? 比如javascript的绝大多数数据(let var命名的变量,对象等)其实就是可变数据

// 比如说这种情况

var a  = {
  x: 1
}

var b = a
b.x = 2
console.log(a.x)

// 再来举一个react的例子

https://codesandbox.io/s/dreamy-panka-de7u9?file=/src/App.js:153-171

// 那常规得解决方式无非是深拷贝
var b = clouedeep(a)
b.x = 2

但是深拷贝在频繁的操作当中,比较消耗内存,性能很差

那如果尝试使用immutable呢?

immutable库

immutable.js

https://www.npmjs.com/package/immutable

immutable介绍 对immutable对象的任何修改或删除添加都会返回一个新的immutable对象。
概念: Map List

import { Map } from 'immutable';
let a = Map({
  select: 'users',
  filter: Map({ name: 'Cam' })
})
let b = a.set('select', 'people');

a === b; // false
a.get('filter') === b.get('filter'); // true

immer.js

https://www.npmjs.com/package/immer

immer当中没有单独的数据类型

import { produce } from 'immer'
var a  = {
   x: 1
}

var b = immer.produce()
b = immer.produce((draft) => {
    draft.x = 2
})
// b.x = 2

console.log(b)  答案是什么?

有人会说用...展开语法不就解决了react的这个setState的问题吗?

let [t, setT] = useState({ a: 1 });
setT((state) => {
    ...t,
    t.a: 2
});
 
// 但下面这种情况呢? 
let [adress, setAdress] = useState({
  phone: 123,
  city: {
    code: '1234',
    area: 'beijing'
  }
})

setAdress({
  ...address,
  city: {
    ...address.city,
    area: "Chengd"
  }
})

但是如果使用immer解决上述React遇到的问题

   let [t, setT] = useState({ a: 1 });
   setT(
      produce(t, (t) => {
         t.a = 2;
      })
   );
   
   // 第二个复杂数据的例子
   setAdress(prevState => produce(prevState, (draftState) = > {
    draftState.address.city.area = 'JingAn'
    draftState.address.postcode += 10
   })
   

   // 进一步简写
    setAdress(
      produce((draftState) => {
        draftState.address.city.area = 'JingAn'
        draftState.address.postcode += 10
      })
   )

不可变数据的应用范围

  • react setState

    import { produce } from 'immer'
    let [t, setT] = useState({ a: 1 });
        setT(
            produce(t, (t) => {
              t.a = 2;
            }
        )
    );
    

    if use use-immer

    import useImmer from 'use-immer'
    const [immer, setImmer] = useImmer({
      name: "Ming",
      sex: 'femal',
      age: 18
    })
    
    setImmmer(draft => {
      draf.age ++
    })
    
  • react redux

下面介绍一下redux的immer应用(可以参考redux的例子里的src/reducers/index.js尝试一下)
https://github.com/reactjs/redux/tree/master/examples/counter

// 不使用 immer
export default (state = { count: 0 }, action) => {
  switch (action.type) {
    case "INCREMENT":
      return {
        count: state.count + 1
      };
    case "DECREMENT":
      return {
        count: state.count - 1
      };
    default:
      return state;
  }
};

// 使用 immer 后
export default (state = { count: 0 }, action) =>
  produce(state, (draftstate) => {
    if (action.type == "INCREMENT") {
      draftstate.count += 1;
    } else if (action.type == "DECREMENT") {
      draftstate.count -= 1;
    }
  });

  • 复制粘贴 前进后退 时间穿梭

    var a = {x: 1}
    var history = []
    history.push(a)
    history.push(produce(a => { a.x = 2 })
    

相关文章

  • 05-JavaScript数组

    JavaScript数组 专门用于存储一组数据的,不是基本数据类型,是引用数据类型(对象类型) 创建数组let 变...

  • JavaScript不可变数据

    什么是数据不可变 数据一旦创建,就不可更改 immutable对象是不可直接赋值的对象,它可以有效的避免错误赋值的...

  • javascript

    javascript显示数据 JavaScript 显示数据 JavaScript 可以通过不同的方式来输出数据:...

  • 了解JavaScript中的七种数据类型

    了解JavaScript中的七种数据类型 JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变...

  • python 列表-元组

    特性: 元组的数据是不可修改的 元组变列表: 列表转元组:

  • @芥末的糖-----immutable.js

    1.immutable为什么要用? 利用这个库来实现数据的表现方式,加强数据的不可变性 JavaScript 中的...

  • JS基本_2018-07-09

    javascript的组成 javascript的语法 javascript的数据类型: 查看数据类型 javas...

  • 走进Angular4的大门

    版本发行速度 Angular2 Angular新架构 javascript不可变对象 组件类 数据绑定 依赖注入 ...

  • javascript学习思维导图

    JavaScript 数据类型 JavaScript 变量 Javascript 运算符 JavaScript 流...

  • JavaScript的数据类型如何判断

    JavaScript的数据类型如何判断 使用 Javascript 的软件项目 JavaScript数据类型一共有...

网友评论

      本文标题:JavaScript不可变数据

      本文链接:https://www.haomeiwen.com/subject/ifzkgltx.html