JavaScript object: var profile = { name: 'Scott', user_id: 42, pic: 'https://scott.mn/me.jpg', friends: [... array of objects ...], latest_tweets: [... array of objects ...], ... }; When one piece of data, let’s say the profile pic, changes: profile.pic = 'https://scott.mn/me2.jpg';
for (var i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } var FriendsView = { render: function(profile) { if (arrayEqual(profile.friends, this_lastFriendsValue)) { return; } // use .slice() to make a copy this._lastFriendsValue = profile.friends.slice(); // ... actually update the DOM ... } }
app in a tree of immutable collections. ❖ Keep a stack of all the states you’ve ever seen, pushing the new state into the stack when something changes. ❖ Pop the stack when the user wants to undo.
you is the options hashes many JavaScript APIs take: var options = {foo: true}; lib.doAThing(options); lib.doAnotherThing(options); Innocuous enough, but what if the library is doing something like this: exports.doAThing = function(options) { // prepare in some way whatever(); // then delegate to another method options.silent = true; exports.doAnotherThing(options); }; exports.doAnotherThing = function(options) { // ... behaves completely differently if options.silent is true ... };
// { foo: 'original' } obj.foo = "mutated!"; notFullyImmutable.get(0) // { foo: 'mutated!' } Problem 1: Like Object.freeze, the collections are only shallowly immutable. In other words, any mutable objects we place in immutable.js collections remain mutable.
back and forth to go from immutable.js collections to vanilla JS collections. It surely wasn’t as bad as the quick-and-dirty “serialize to JSON” hack would have been, but it was a recurring pain nevertheless. var hobbits = Immutable.fromJS([{name: "Frodo"}, {name: "Samwise"}, {name: "Meriadoc"}]) _.pluck(hobbits, "name") // Runtime exception _.pluck(hobbits.toJS(), "name") // ["Frodo", "Samwise", "Meriadoc"]
realizing we could use much of Underscore’s library of functions as normal. When we wanted to use _.max or _.find, we passed them a seamless-immutable array and everything just worked.
is to use asMutable, which returns a vanilla JS array representation of a seamless-immutable array. Another is to use another library’s map function, such as _.map from Underscore. In CoffeeScript, you also can use a list comprehension (for…in) instead of map to similar effect. https://github.com/u2/react-alt-demo/blob/master/assets/javascripts/components/ CommentList.jsx https://github.com/facebook/immutable-js#embraces-es6