我最近一直在研究同一个话题.我会尽我所能回答你的问题,并try 分享到目前为止我所学到的东西.
问题是,为什么不变性如此重要?这有什么问题吗
基本上,它归结为这样一个事实:不变性(间接地)提高了可预测性和性能,并允许进行Mutations 跟踪.
Predictability
Mutations 隐藏了变化,而变化会产生(意想不到的)副作用,从而导致讨厌的虫子.当您强制执行不变性时,您可以保持应用程序架构和心智模型的简单,这使您更容易对应用程序进行推理.
Performance
即使向不可变对象添加值意味着需要创建一个新实例,其中需要复制现有值,并且需要向新对象添加新值,这会消耗内存,但不可变对象可以利用 struct 共享来减少内存开销.
所有更新都会返回新值,但内部 struct 会共享给
你可以阅读更多关于这here的信息.
Mutation Tracking
除了减少内存使用,不变性还允许您通过使用引用和值相等来优化应用程序.这就很容易看出是否有什么变化.例如,react组件中的状态更改.可以使用shouldComponentUpdate
通过比较状态对象来判断状态是否相同,并防止不必要的渲染.
额外资源:
如果我设置一个数组,比如一个初始值为的对象array.我不能
是的,这是正确的.如果你对如何在你的应用程序中实现这一点感到困惑,我建议你看看redux是如何做到这一点的,以熟悉核心概念,这对我有很大帮助.
我喜欢以Redux为例,因为它包含不变性.它有一个单一的不可变状态树(称为store
),其中所有状态更改都是通过调度操作显式进行的,这些操作由一个reducer处理,reducer接受前一个状态和所述操作(一次一个),并返回应用程序的下一个状态.你可以阅读更多关于它的核心原则here.
有一个关于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();
此外,这些视频还进一步详细演示了如何实现以下各项的不变性: