# JavaScript 中的 不变性（Immutability）

## 什么是不变性？

``````var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);
``````

## In JavaScript, Mutability Abounds

``````var arr = [];
var v2 = arr.push(2);
``````

`v2`的值是多少？如果数组与字符串和数字的处理一致，`v2`将包含一个新数组，其中包含一个元素 - 数字2 - 。然而，这种情况并非如此。相反，`arr`引用已被更新为包含数字，`v2`的值是`arr`的新长度。

``````var arr = new ImmutableArray([1, 2, 3, 4]);
var v2 = arr.push(5);

arr.toArray(); // [1, 2, 3, 4]
v2.toArray();  // [1, 2, 3, 4, 5]
``````

``````var person = new ImmutableMap({name: "Chris", age: 32});
var olderPerson = person.set("age", 33);

person.toObject(); // {name: "Chris", age: 32}
olderPerson.toObject(); // {name: "Chris", age: 33}
``````

## JavaScript中不变性的实践

``````function createGame(options) {
return Immutable.fromJS({
cols: options.cols,
rows: options.rows,
tiles: initTiles(options.rows, options.cols, options.mines)
});
}
``````

``````function revealTile(game, tile) {
game.tiles[tile].isRevealed = true;
}
``````

``````function revealTile(game, tile) {
var updatedTile = game.get('tiles').get(tile).set('isRevealed', true);
var updatedTiles = game.get('tiles').set(tile, updatedTile);
return game.set('tiles', updatedTiles);
}
``````

``````function revealTile(game, tile) {
return game.setIn(['tiles', tile, 'isRevealed'], true);
}
``````

``````function revealTile(game, tile) {
return game.getIn(['tiles', tile]) ?
game.setIn(['tiles', tile, 'isRevealed'], true) :
game;
}
``````

## 改进变更追踪

``````var tiles = [{id: 0, isRevealed: false}, {id: 1, isRevealed: true}];
Object.observe(tiles, function () { /* ... */ });

tiles[0].id = 2;
``````

“tile [0]”对象的突变不会触发我们的突变观察者，因此，提出的突变跟踪机制甚至无法使用最简单的用例。不变性在这种情况下如何解决？给定应用程序状态`a`，并且可能是新的应用程序状态`b`

``````if (a === b) {
// Data didn't change, abort
}
``````