02 | 如何通过闭包对象管理程序中状态的变化?
值的(不)可变
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了在函数式编程中如何通过闭包对象管理程序状态的变化。首先介绍了函数式编程中的副作用和纯函数的概念,以及在不可变原则下管理状态变化的重要性。随后分析了JavaScript中的原始类型和对象类型的可变性,以及React.js中的props和state的使用。重点讨论了闭包和对象在封装状态和创建行为方面的作用,并对它们在隐私、状态拷贝和性能等方面的差异进行了比较。文章还探讨了属性的查改操作对闭包和对象的影响,并介绍了通过Object.freeze()方法实现对象属性的只读设置。总结指出,在React.js中,对象作为props和state的值类型更容易保证属性和状态值的整体不可变,更易于拷贝,并在处理高频交互时性能更佳。而闭包虽有隐私上的优势和更细粒度的操作,但在应用交互和状态管理方面并没有实际作用。最后强调了根据具体情况确定哪种方式更适合程序和应用所需支持的场景。整体而言,本文通过具体的例子和分析,为读者提供了深入的技术理解和应用指导。
《JavaScript 进阶实战课》,新⼈⾸单¥59
全部留言(15)
- 最新
- 精选
- WGH丶有一个说法是:闭包是带数据的行为,对象是带行为的数据。
作者回复: 很好地描述了两者相对的从属关系
2022-09-28归属地:北京39 - I keep my ideals💤如果要实现值的绝对不可变应该使用深拷贝,这样对拷贝出来的复杂数据结构进行修改时才能保证不会对原始数据造成影响
作者回复: 是的
2022-09-22归属地:北京7 - 谷岳spread 展开语法仅能做到浅拷贝,因为仅遍历一层。在开发中,比较常用的深拷贝方式是:JSON.parse(JSON.stringify(obj))。虽然stringify方法在转化JSON字符串时有不少特殊状况。这种方式不会影响状态,因为stringify方法返回的是一个常量字符串。
作者回复: 是的,虽然React.PureComponent中的shouldComponentUpdate() 基于性能考虑,不建议用深对比和JSON.stringify();但如果程序中确实是需要处理复杂的数据结构变化的话,可以用force update或immutable-js来满足类似的需求。
2022-09-22归属地:北京5 - 雨中送陈萍萍好像要老师画图的软件,老师可以告知一下麽
作者回复: Mac自带的keynote,没有特别的工具哈,类似于Windows中的ppt。
2022-11-03归属地:北京2 - Alison通常更新state的时候框架会用Object.is来判断2个数组/对象是否相等,浅拷贝对象时,因拷贝的是引用地址,所以Object.is对比后的返回值会是true,状态就无法正常更新; 深拷贝对象的话,拷贝的是值,此时会产生新的引用地址,所以Object.is对比后的返回值是false,状态会进行更新
作者回复: 在React,早期有一个shallowCompare附加功能,后面被React.memo和React.PureComponent取代了,但是底层逻辑类似,仍然是一个浅对比。如果想对比更复杂的对象,React.memo也支持在第二个实参传入自定义的对比功能。
2022-09-22归属地:北京2 - Hello,Tomrrow对象或数组的浅拷贝,是简单的值的复制,这对于对象属性值或数组元素是简单类型来说没有问题;如果对象属性值或数组元素是复杂类型,存的是一个内存地址,对内存地址的复制,只是多了一个指向同一个空间的指针。这时需要进行深拷贝,常用的方式通过递归的方式。 深拷贝,是不会影响状态管理的。
作者回复: 深拷贝的简单实现是JSON.parse(JSON.stringify(obj)),不过考虑到JSON safe和性能问题,递归是会更好一些。 React中的setState()是浅合并而不是深拷贝,会不会影响看情况,如果是“复杂类型”也就是嵌套对象,那就会被影响了。
2022-09-22归属地:北京2 - Change文中提到闭包比较难实现拷贝,比较有疑问? 1. 闭包如果返回属性则失去对属性保护的意义。 2. 如果不返回通过哪种方式是实现属性拷贝。
作者回复: 1. 闭包如果返回属性则失去对属性保护的意义。 --------------------------------- 是的,所以对象的属性是公开的,闭包的意义就是隐藏。 2. 如果不返回通过哪种方式是实现属性拷贝。 --------------------------------- 这种情况下,就要在闭包嵌套层加获取权限的方法。
2022-10-11归属地:北京1 - 奕晨spread 做到的是浅拷贝,那么你是否了解与之对应的深度拷贝? 需要根据数据类型区分,若是对象的话,浅拷贝后,修改其中一个值,会影响另一个值,拷贝的是对象的地址;深度拷贝就是重新创建一个新的地址,修改其中的值,互不影响。 它会不会影响状态的管理? 需要针对props 和state区分,根据值的类型判断,props不会,state会影响。
作者回复: 对于嵌套的对象,是有这样的影响。
2022-09-22归属地:北京1 - 海比如下面的 [3, 1, 0, 7] 这组数组中,我们把第一个值变成 2,第三个值变成 6,第 4 个值添加 1,形成了 [2, 1, 0, 6, 1]。 老师,这里没太理解呢,第3个值变成6,不是 2,1,6 吗?
作者回复: 可能是描述的问题,我再改改。因为是数组,这里我们从0开始计算第一位,然后第3个值变成6是第四位,再然后第4个值添加1是第五位。
2022-11-01归属地:北京2 - 哎呦先生老师,扩展运算符例子那数组元素用引用类型的数据结构是不是比较合理,原始类型的数据无法深拷贝浅拷贝的内存地址区别,容易迷糊。
作者回复: 这里咱们用的数组和对象就是引用类型的数据结构哈。 举个例子: var a = [1,2,3]; var b = a; a[3] = 4; console.log(b); //返回 [1,2,3,4] 你可以看到b引用的是a的数组中的元素。
2022-10-31归属地:北京