02 | 如何通过闭包对象管理程序中状态的变化?
02 | 如何通过闭包对象管理程序中状态的变化?
讲述:石川
时长11:07大小10.15M
值的(不)可变
React.js 中的 props 和 state
结构型值的不可变
闭包和对象
属性的查改
状态的拷贝
性能的考虑
总结
思考题
延伸阅读
赞 6
提建议
精选留言(13)
- WGH丶2022-09-28 来自北京有一个说法是:闭包是带数据的行为,对象是带行为的数据。
作者回复: 很好地描述了两者相对的从属关系
24 - I keep my ideals...2022-09-22 来自北京如果要实现值的绝对不可变应该使用深拷贝,这样对拷贝出来的复杂数据结构进行修改时才能保证不会对原始数据造成影响
作者回复: 是的
5 - John Bull2022-09-22 来自北京spread 展开语法仅能做到浅拷贝,因为仅遍历一层。在开发中,比较常用的深拷贝方式是:JSON.parse(JSON.stringify(obj))。虽然stringify方法在转化JSON字符串时有不少特殊状况。这种方式不会影响状态,因为stringify方法返回的是一个常量字符串。
作者回复: 是的,虽然React.PureComponent中的shouldComponentUpdate() 基于性能考虑,不建议用深对比和JSON.stringify();但如果程序中确实是需要处理复杂的数据结构变化的话,可以用force update或immutable-js来满足类似的需求。
4 - Alison2022-09-22 来自北京通常更新state的时候框架会用Object.is来判断2个数组/对象是否相等,浅拷贝对象时,因拷贝的是引用地址,所以Object.is对比后的返回值会是true,状态就无法正常更新; 深拷贝对象的话,拷贝的是值,此时会产生新的引用地址,所以Object.is对比后的返回值是false,状态会进行更新
作者回复: 在React,早期有一个shallowCompare附加功能,后面被React.memo和React.PureComponent取代了,但是底层逻辑类似,仍然是一个浅对比。如果想对比更复杂的对象,React.memo也支持在第二个实参传入自定义的对比功能。
2 - 奕晨2022-09-22 来自北京spread 做到的是浅拷贝,那么你是否了解与之对应的深度拷贝? 需要根据数据类型区分,若是对象的话,浅拷贝后,修改其中一个值,会影响另一个值,拷贝的是对象的地址;深度拷贝就是重新创建一个新的地址,修改其中的值,互不影响。 它会不会影响状态的管理? 需要针对props 和state区分,根据值的类型判断,props不会,state会影响。展开
作者回复: 对于嵌套的对象,是有这样的影响。
1 - Hello,Tomrrow2022-09-22 来自北京对象或数组的浅拷贝,是简单的值的复制,这对于对象属性值或数组元素是简单类型来说没有问题;如果对象属性值或数组元素是复杂类型,存的是一个内存地址,对内存地址的复制,只是多了一个指向同一个空间的指针。这时需要进行深拷贝,常用的方式通过递归的方式。 深拷贝,是不会影响状态管理的。展开
作者回复: 深拷贝的简单实现是JSON.parse(JSON.stringify(obj)),不过考虑到JSON safe和性能问题,递归是会更好一些。 React中的setState()是浅合并而不是深拷贝,会不会影响看情况,如果是“复杂类型”也就是嵌套对象,那就会被影响了。
1 - Nuvole Bianche2023-01-14 来自上海也许一方面是我自身的能力没达到一定高度,另一方面也感觉作者大大总是用一些看上去比较“假大空”的词汇。每当自己看到这些词汇时,有些不知所云,一时难以理解。然后自己试着根据自己已有的知识,找一个可能与之对应、但更实在的词汇来代替时,就突然明白,原来作者是这个意思呀。 比如原文中:所以,它其实可以细粒度地控制我们想要暴露或隐藏的属性,以及相关的操作。 这个细粒度说白了不就是更加可预测和可控吗? 可偏偏搞个大词,还是有些不习惯。 可能这就是作者在开篇说的入门既是巅峰者对菜鸡小白的俯视吧。 我还是的咬牙坚持一下。展开
- 雨中送陈萍萍2022-11-03 来自北京好像要老师画图的软件,老师可以告知一下麽
作者回复: Mac自带的keynote,没有特别的工具哈,类似于Windows中的ppt。
- 海2022-11-01 来自北京比如下面的 [3, 1, 0, 7] 这组数组中,我们把第一个值变成 2,第三个值变成 6,第 4 个值添加 1,形成了 [2, 1, 0, 6, 1]。 老师,这里没太理解呢,第3个值变成6,不是 2,1,6 吗?
作者回复: 可能是描述的问题,我再改改。因为是数组,这里我们从0开始计算第一位,然后第3个值变成6是第四位,再然后第4个值添加1是第五位。
共 2 条评论 - 哎呦先生2022-10-31 来自北京老师,扩展运算符例子那数组元素用引用类型的数据结构是不是比较合理,原始类型的数据无法深拷贝浅拷贝的内存地址区别,容易迷糊。
作者回复: 这里咱们用的数组和对象就是引用类型的数据结构哈。 举个例子: var a = [1,2,3]; var b = a; a[3] = 4; console.log(b); //返回 [1,2,3,4] 你可以看到b引用的是a的数组中的元素。
- Change2022-10-11 来自北京文中提到闭包比较难实现拷贝,比较有疑问? 1. 闭包如果返回属性则失去对属性保护的意义。 2. 如果不返回通过哪种方式是实现属性拷贝。
作者回复: 1. 闭包如果返回属性则失去对属性保护的意义。 --------------------------------- 是的,所以对象的属性是公开的,闭包的意义就是隐藏。 2. 如果不返回通过哪种方式是实现属性拷贝。 --------------------------------- 这种情况下,就要在闭包嵌套层加获取权限的方法。
- Chaos浩2022-09-22 来自北京闭包和bind,经常见到这两个概念但一直一知半解,这一课看完豁然开朗
作者回复: 很高兴能帮助你理解
- RichardZhang2022-09-22 来自北京好文打卡,期待周六。
作者回复: 我们周六见