- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我目前正在处理 React JS和 React Native构架。在中途我遇到了 Immutability 或 Immutable-JS library ,当我阅读 Facebook 的 Flux 和 Redux 实现时。
问题是,为什么不变性如此重要?改变对象有什么问题?这不是让事情变得简单吗?
举个例子,让我们考虑一个简单的新闻阅读器应用,其起始屏幕是新闻标题的 ListView 。
如果我设置一个 对象数组 的值最初,我无法操作它。这就是不变性原理所说的,对吧? (如果我错了,请纠正我。)但是,如果我有一个必须更新的新 News 对象怎么办?在通常情况下,我可以将对象添加到数组中。在这种情况下我该如何实现?删除商店并重新创建它?向数组中添加对象不是成本更低的操作吗?
最佳答案
我最近一直在研究同一主题。我会尽力回答您的问题并尝试分享我到目前为止所学到的知识。
The question is, why is immutability so important? What is wrong in mutating objects? Doesn't it make things simple?
基本上归结为不变性提高了可预测性、性能(间接)并允许进行突变跟踪这一事实。
可预测性
突变隐藏了变化,这会产生(意想不到的)副作用,这可能会导致令人讨厌的错误。当您强制执行不变性时,您可以使您的应用程序架构和心智模型保持简单,从而更容易推理您的应用程序。
性能
尽管向不可变对象(immutable对象)添加值意味着需要在需要复制现有值的地方创建一个新实例,并且需要将新值添加到新对象中,这会消耗内存,但不可变对象(immutable对象)可以利用结构共享以减少内存开销。
All updates return new values, but internally structures are shared to drastically reduce memory usage (and GC thrashing). This means that if you append to a vector with 1000 elements, it does not actually create a new vector 1001-elements long. Most likely, internally only a few small objects are allocated.
您可以阅读更多关于此 here 的信息.
突变跟踪
除了减少内存使用量之外,不变性还允许您通过使用引用和值相等来优化您的应用程序。这使得很容易查看是否有任何变化。例如, react 组件中的状态变化。您可以使用 shouldComponentUpdate
通过比较状态对象来检查状态是否相同,并防止不必要的渲染。你可以阅读更多关于这个 here .
其他资源:
If I set say an array of objects with a value initially. I can't manipulate it. That's what immutability principle says, right?(Correct me if I am wrong). But, what if I have a new News object that has to be updated? In usual case, I could have just added the object to the array. How do I achieve in this case? Delete the store & recreate it? Isn't adding an object to the array a less expensive operation?
是的,这是正确的。如果您对如何在应用程序中实现这一点感到困惑,我建议您查看 redux这样做是为了熟悉核心概念,对我帮助很大。
我喜欢使用 Redux 作为示例,因为它包含不变性。它有一个单一的不可变状态树(称为store
),其中所有状态更改都是通过调度由reducer 处理的操作来显式的,该reducer 接受先前的状态以及所述操作(一次一个)并返回应用程序的下一个状态。您可以阅读更多关于它的核心原则 here .
egghead.io 上有一个很棒的 redux 类(class)在哪里 Dan Abramov redux 的作者,对这些原则的解释如下(我稍微修改了代码以更好地适应场景):
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();
此外,这些视频更详细地演示了如何实现以下方面的不变性:
关于javascript - 为什么 JavaScript 中的不变性如此重要(或需要)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34385243/
我是一名优秀的程序员,十分优秀!