不变性的相反观点
TL / DR:不变性是一种时尚趋势,而不是JavaScript中的必要性。如果您使用的是React,它确实为状态管理中一些令人困惑的设计选择提供了一种简洁的解决方法。但是,在大多数其他情况下,它并不能为其引入的复杂性增加足够的价值,更多的是用来填补简历,而不是满足客户的实际需求。
长答案:请阅读以下内容。
为什么不变性在javascript中如此重要(或需要)?
好吧,很高兴你问!
前一段时间,一个非常有才华的人Dan Abramov编写了一个名为Redux的javascript状态管理库,该库使用纯函数和不变性。他还制作了一些非常酷的视频,使这个想法非常容易理解(和出售)。
时机是完美的。Angular的新颖性正在逐渐消失,JavaScript世界已准备好专注于具有合适程度的最新事物,并且该库不仅具有创新性,而且与React完美地结合在一起,React由另一个硅谷强者兜售。
不幸的是,时尚在JavaScript世界中占统治地位。现在,阿布拉莫夫被誉为半神半兽,而我们所有人凡人都必须服从于不变性之道 ……无论它是否有意义。
更改对象有什么问题?
没有!
实际上,程序员已经将对象突变了……只要存在可以突变的对象。换句话说,超过50年的应用程序开发。
为什么使事情复杂化?当您发现对象cat
并死亡时,您是否真的需要一秒钟cat
来跟踪更改?大多数人只会说cat.isDead = true
并完成它。
(更改对象)不是使事情简单吗?
是!..当然可以!
特别是在JavaScript中,实际上,JavaScript最有用用于呈现在其他位置(例如数据库中)维护的某些状态的视图。
如果我有一个新的News对象必须更新怎么办?...在这种情况下如何实现?删除商店并重新创建?是不是将对象添加到数组中的开销较小?
好了,您可以采用传统方法并更新News
对象,因此该对象的内存表示形式会发生变化(以及向用户显示的视图,或者有人希望如此)...
或者...
您可以尝试使用性感的FP / Immutability方法,并将对News
对象的更改添加到跟踪每个历史更改的数组中,以便随后遍历数组并找出正确的状态表示形式(phe!)。
我正在尝试了解这里的内容。请赐教:)
时尚来来去去哥们。有很多方法可以给猫皮。
抱歉,您不得不承受一套不断变化的编程范例的困惑。但是,嘿,欢迎来到俱乐部!
现在要牢记关于不变性的两个重要要点,您将以只有天真才能发扬的狂热强度将它们扔给您。
1)不可变性对于避免多线程环境中的竞争条件非常有用。
当多个线程想要更改对象时,多线程环境(如C ++,Java和C#)会犯锁定对象的做法。这对性能不利,但比替代数据损坏更好。但是还不如使所有东西都变得不可变(上帝赞美Haskell!)。
可惜!在JavaScript中,您总是在单个线程上操作。甚至是网络工作者(每个人都在单独的上下文中运行)。因此,由于您在执行上下文(所有可爱的全局变量和闭包)中无法拥有与线程相关的竞争条件,因此支持不可变性的要点不在窗外。
(话虽如此,有是一个优势,在网络工作者,这是,你有没有关于与主线程上的对象摆弄的预期使用纯函数。)
2)不变性可以(以某种方式)避免应用状态下的竞争情况。
这才是真正的症结所在,大多数(反应)开发人员都会告诉您,不变性和FP可以某种方式发挥作用,从而使应用程序的状态变得可预测。
当然,这并不意味着您可以避免数据库中出现争用情况,要想摆脱这种情况,就必须协调所有浏览器中的所有用户,为此,您需要像WebSockets这样的后端推送技术(详情请参见下文),它将向运行该应用程序的每个人广播更改。
这也不意味着JavaScript中存在一些内在的问题,即您的应用程序状态需要不可改变性才能变得可预测,任何在React之前编写前端应用程序的开发人员都会告诉您这一点。
这个相当令人困惑的说法只是意味着使用React,您的应用程序状态将变得更容易出现竞争状况,但是不变性可以使您减轻痛苦。为什么?因为React是特殊的..它被设计为高度优化的渲染库,其连贯状态管理位居第二,因此,组件状态通过您无法控制的异步事件链(也称为“单向数据绑定”)进行管理结束并依靠你记住不要直接改变状态 ...
在这种情况下,很容易看出对不变性的需求与JavaScript无关,而与React中的竞争条件有很大关系:如果您的应用程序中有许多相互依赖的更改,并且没有简单的方法来找出原因您目前处于状态,您会感到困惑,因此使用不变性来跟踪每一个历史变化都是很有意义的。
3)比赛条件绝对不好。
好吧,如果您使用的是React,那么可能就是这样。但是,如果您选择其他框架,它们很少见。
此外,您通常要处理更大的问题 ……诸如依赖地狱之类的问题。就像a肿的代码库。就像您的CSS无法加载一样。就像缓慢的构建过程或卡在整体后端上,使得几乎不可能进行迭代。就像没有经验的开发人员一样,他们也不了解正在发生的事情并弄乱了事情。
你懂。现实。但是,嘿,谁在乎呢?
4)不变性利用引用类型来减少跟踪每个状态变化对性能的影响。
因为认真的说,如果您每次状态更改时都打算复制内容,那么最好确保您对此有所了解。
5)不变性使您可以撤消东西。
因为er ..这是您的项目经理想要的第一功能,对吧?
6)不可变状态与WebSocket结合具有很大的潜力
最后但并非最不重要的一点是,与WebSocket结合使用时,状态增量的累积成为了一个令人信服的案例,它允许将状态作为不可变事件流轻松消耗...
一旦一分钱都落在了这个概念上(状态是事件的流转,而不是代表最近观点的原始记录集),不可变的世界将成为一个神奇的居住地。一个源于事件的奇妙和可能性的土地,它超越了时间本身。并在完成后右这个绝对可以让实时应用程式EASI 呃来完成,你只播事件给大家感兴趣,所以他们的流动建立自己表示本和自己的变化写回社区流动。
但是到了某个时刻,您醒来并意识到,所有的奇观和魔力都不是免费的。与您渴望的同事不同,您的利益相关者(是的,付钱给您的人)很少关心哲学或时尚,而关心他们为打造可销售产品而付出的金钱。最重要的是,它更难编写不可变的代码,更容易破坏它,而且如果没有后端来支持不可变的前端,那就毫无意义。当(如果!!)最终使您的利益相关者相信您应该通过WebSockets之类的推送技术发布和使用事件时,您将发现在生产中进行扩展会带来什么痛苦。
现在寻求一些建议,您是否应该选择接受它。
使用FP / Immutability编写JavaScript的选择也是使应用程序代码库更大,更复杂且更难管理的选择。我强烈建议将这种方法限制在您的Redux reducer上,除非您知道自己在做什么...而且如果您要继续使用不可变性,无论如何,然后将不可变状态应用于整个应用程序堆栈,而不仅限于客户端,否则您将失去它的真正价值。
现在,如果您有幸能够在工作中做出选择,那么请尝试(或不使用)您的智慧,并付钱给您的人做对的事情。您可以根据自己的经验,内心或周围发生的事情(当然,如果每个人都在使用React / Redux,那么会有一个有效的论据,那就是找到资源来继续您的工作会更容易)。您可以尝试“ 恢复驱动开发”或“ 炒作驱动开发”方法。它们可能更像您的事情。
总之,可以说对于不变性的事情是,它会令你的时尚与您同行,至少直到下一个热潮来临时,由此时你会很高兴地前进。
现在,在本次自我治疗之后,我想指出的是,我已将其作为文章添加到我的博客中=> JavaScript中的不变性:反向视图。如果您有强烈的感觉,也可以在这里回复;)。