我最近一直在研究同一主题。我会尽力回答您的问题,并尝试分享到目前为止我学到的知识。
问题是,为什么不变性如此重要?更改对象有什么问题?它不是使事情变得简单吗?
基本上可以归结为不变性增加了(间接)可预测性,性能和允许进行突变跟踪的事实。
可预测性
突变会隐藏变化,从而产生(意外的)副作用,这可能会导致讨厌的错误。当您实施不变性时,可以使您的应用程序体系结构和思维模型保持简单,这使得对应用程序的推理更加容易。
性能
尽管向不可变对象添加值意味着需要在需要复制现有值的情况下创建新实例,并且需要向新对象添加新值,这会消耗内存,但不可变对象可以利用结构共享来减少内存高架。
所有更新都返回新值,但是内部结构被共享以大大减少内存使用(和GC崩溃)。这意味着,如果将一个向量附加到具有1000个元素的向量上,则实际上不会创建1001个元素长的新向量。内部很可能只分配了几个小对象。
您可以在此处了解更多信息。
变异追踪
除了减少内存使用量之外,不变性还允许您通过使用引用和值相等来优化应用程序。这使得查看任何更改是否真的很容易。例如,反应组件的状态变化。您可以
shouldComponentUpdate通过比较状态对象来检查状态是否相同,并防止不必要的渲染。您可以在此处了解更多信息。
其他资源:
- 不变性的道
- 不变的数据结构和Javascript
- Javascript的不变性
如果我设置,说一个对象数组最初带有一个值。我无法 *** 纵它。这就是不变性原则的意思,对吗?(如果我错了,请纠正我)。但是,如果我有一个新的News对象必须更新怎么办?在通常情况下,我可以将对象添加到数组中。在这种情况下我该如何实现?删除商店并重新创建?是不是将对象添加到数组中的开销较小?
是的,这是正确的。如果您对如何在应用程序中实现此方法感到困惑,我建议您看看redux是如何做到的以熟悉核心概念,这对我有很大帮助。
我喜欢以Redux为例,因为它具有不变性。它具有一个不变的状态树(称为
store),其中所有状态更改都是通过调度动作来显式显示的,该动作由化简器处理,该化简器接受前一个状态以及所述动作(一次一个)并返回应用程序的下一个状态。您可以在此处阅读有关其核心原理的更多信息。
egghead.io上有一个很棒的redux课程,redux的作者Dan
Abramov解释了以下原理(我对代码进行了一些修改以更好地适应这种情况):
import React from 'react';import ReactDOM from 'react-dom';// Reducer.const news = (state=[], action) => { switch(action.type) { case 'ADD_NEWS_ITEM': { return [ ...state, action.newsItem ]; } default: { return state; } }};// Store.const createStore = (reducer) => { let state; let listeners = []; const subscribe = (listener) => { listeners.push(listener); return () => { listeners = listeners.filter(cb => cb !== listener); }; }; const getState = () => state; const dispatch = (action) => { state = reducer(state, action); listeners.forEach( cb => cb() ); }; dispatch({}); return { subscribe, getState, dispatch };};// Initialize store with reducer.const store = createStore(news);// Component.const News = React.createClass({ onAddNewsItem() { const { newsTitle } = this.refs; store.dispatch({ type: 'ADD_NEWS_ITEM', newsItem: { title: newsTitle.value } }); }, render() { const { news } = this.props; return ( <div> <input ref="newsTitle" /> <button onClick={ this.onAddNewsItem }>add</button> <ul> { news.map( ({ title }) => <li>{ title }</li>) } </ul> </div> ); }});// Handler that will execute when the store dispatches.const render = () => { ReactDOM.render( <News news={ store.getState() } />, document.getElementById('news') );};// Entry point.store.subscribe(render);render();
此外,这些视频进一步详细展示了如何实现以下方面的不变性:
- 数组
- 对象
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)