source: node_modules/immutable/README.md@ 65b6638

main
Last change on this file since 65b6638 was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 16.7 KB
Line 
1Immutable collections for JavaScript
2====================================
3
4[![Build Status](https://travis-ci.org/facebook/immutable-js.svg)](https://travis-ci.org/facebook/immutable-js)
5
6[Immutable][] data cannot be changed once created, leading to much simpler
7application development, no defensive copying, and enabling advanced memoization
8and change detection techniques with simple logic. [Persistent][] data presents
9a mutative API which does not update the data in-place, but instead always
10yields new updated data.
11
12Immutable.js provides many Persistent Immutable data structures including:
13`List`, `Stack`, `Map`, `OrderedMap`, `Set`, `OrderedSet` and `Record`.
14
15These data structures are highly efficient on modern JavaScript VMs by using
16structural sharing via [hash maps tries][] and [vector tries][] as popularized
17by Clojure and Scala, minimizing the need to copy or cache data.
18
19`Immutable` also provides a lazy `Seq`, allowing efficient
20chaining of collection methods like `map` and `filter` without creating
21intermediate representations. Create some `Seq` with `Range` and `Repeat`.
22
23Want to hear more? Watch the presentation about Immutable.js:
24
25<a href="https://youtu.be/I7IdS-PbEgI" target="_blank" alt="Immutable Data and React"><img src="https://img.youtube.com/vi/I7IdS-PbEgI/0.jpg" /></a>
26
27[Persistent]: http://en.wikipedia.org/wiki/Persistent_data_structure
28[Immutable]: http://en.wikipedia.org/wiki/Immutable_object
29[hash maps tries]: http://en.wikipedia.org/wiki/Hash_array_mapped_trie
30[vector tries]: http://hypirion.com/musings/understanding-persistent-vector-pt-1
31
32
33Getting started
34---------------
35
36Install `immutable` using npm.
37
38```shell
39npm install immutable
40```
41
42Then require it into any module.
43
44```javascript
45var Immutable = require('immutable');
46var map1 = Immutable.Map({a:1, b:2, c:3});
47var map2 = map1.set('b', 50);
48map1.get('b'); // 2
49map2.get('b'); // 50
50```
51
52### Browser
53
54To use `immutable` from a browser, download [dist/immutable.min.js](https://github.com/facebook/immutable-js/blob/master/dist/immutable.min.js)
55or use a CDN such as [CDNJS](https://cdnjs.com/libraries/immutable)
56or [jsDelivr](http://www.jsdelivr.com/#!immutable.js).
57
58Then, add it as a script tag to your page:
59
60```html
61<script src="immutable.min.js"></script>
62<script>
63 var map1 = Immutable.Map({a:1, b:2, c:3});
64 var map2 = map1.set('b', 50);
65 map1.get('b'); // 2
66 map2.get('b'); // 50
67</script>
68```
69
70Or use an AMD loader (such as [RequireJS](http://requirejs.org/)):
71
72```javascript
73require(['./immutable.min.js'], function (Immutable) {
74 var map1 = Immutable.Map({a:1, b:2, c:3});
75 var map2 = map1.set('b', 50);
76 map1.get('b'); // 2
77 map2.get('b'); // 50
78});
79```
80
81If you're using [browserify](http://browserify.org/), the `immutable` npm module
82also works from the browser.
83
84### TypeScript
85
86Use these Immutable collections and sequences as you would use native
87collections in your [TypeScript](http://typescriptlang.org) programs while still taking
88advantage of type generics, error detection, and auto-complete in your IDE.
89
90Just add a reference with a relative path to the type declarations at the top
91of your file.
92
93```javascript
94///<reference path='./node_modules/immutable/dist/immutable.d.ts'/>
95import Immutable = require('immutable');
96var map1: Immutable.Map<string, number>;
97map1 = Immutable.Map({a:1, b:2, c:3});
98var map2 = map1.set('b', 50);
99map1.get('b'); // 2
100map2.get('b'); // 50
101```
102
103
104The case for Immutability
105-------------------------
106
107Much of what makes application development difficult is tracking mutation and
108maintaining state. Developing with immutable data encourages you to think
109differently about how data flows through your application.
110
111Subscribing to data events throughout your application creates a huge overhead of
112book-keeping which can hurt performance, sometimes dramatically, and creates
113opportunities for areas of your application to get out of sync with each other
114due to easy to make programmer error. Since immutable data never changes,
115subscribing to changes throughout the model is a dead-end and new data can only
116ever be passed from above.
117
118This model of data flow aligns well with the architecture of [React][]
119and especially well with an application designed using the ideas of [Flux][].
120
121When data is passed from above rather than being subscribed to, and you're only
122interested in doing work when something has changed, you can use equality.
123
124Immutable collections should be treated as *values* rather than *objects*. While
125objects represents some thing which could change over time, a value represents
126the state of that thing at a particular instance of time. This principle is most
127important to understanding the appropriate use of immutable data. In order to
128treat Immutable.js collections as values, it's important to use the
129`Immutable.is()` function or `.equals()` method to determine value equality
130instead of the `===` operator which determines object reference identity.
131
132```javascript
133var map1 = Immutable.Map({a:1, b:2, c:3});
134var map2 = map1.set('b', 2);
135assert(map1.equals(map2) === true);
136var map3 = map1.set('b', 50);
137assert(map1.equals(map3) === false);
138```
139
140Note: As a performance optimization `Immutable` attempts to return the existing
141collection when an operation would result in an identical collection, allowing
142for using `===` reference equality to determine if something definitely has not
143changed. This can be extremely useful when used within memoization function
144which would prefer to re-run the function if a deeper equality check could
145potentially be more costly. The `===` equality check is also used internally by
146`Immutable.is` and `.equals()` as a performance optimization.
147
148If an object is immutable, it can be "copied" simply by making another reference
149to it instead of copying the entire object. Because a reference is much smaller
150than the object itself, this results in memory savings and a potential boost in
151execution speed for programs which rely on copies (such as an undo-stack).
152
153```javascript
154var map1 = Immutable.Map({a:1, b:2, c:3});
155var clone = map1;
156```
157
158[React]: http://facebook.github.io/react/
159[Flux]: http://facebook.github.io/flux/docs/overview.html
160
161
162JavaScript-first API
163--------------------
164
165While `immutable` is inspired by Clojure, Scala, Haskell and other functional
166programming environments, it's designed to bring these powerful concepts to
167JavaScript, and therefore has an Object-Oriented API that closely mirrors that
168of [ES6][] [Array][], [Map][], and [Set][].
169
170[ES6]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
171[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
172[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
173[Set]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
174
175The difference for the immutable collections is that methods which would mutate
176the collection, like `push`, `set`, `unshift` or `splice` instead return a new
177immutable collection. Methods which return new arrays like `slice` or `concat`
178instead return new immutable collections.
179
180```javascript
181var list1 = Immutable.List.of(1, 2);
182var list2 = list1.push(3, 4, 5);
183var list3 = list2.unshift(0);
184var list4 = list1.concat(list2, list3);
185assert(list1.size === 2);
186assert(list2.size === 5);
187assert(list3.size === 6);
188assert(list4.size === 13);
189assert(list4.get(0) === 1);
190```
191
192Almost all of the methods on [Array][] will be found in similar form on
193`Immutable.List`, those of [Map][] found on `Immutable.Map`, and those of [Set][]
194found on `Immutable.Set`, including collection operations like `forEach()`
195and `map()`.
196
197```javascript
198var alpha = Immutable.Map({a:1, b:2, c:3, d:4});
199alpha.map((v, k) => k.toUpperCase()).join();
200// 'A,B,C,D'
201```
202
203### Accepts raw JavaScript objects.
204
205Designed to inter-operate with your existing JavaScript, `immutable`
206accepts plain JavaScript Arrays and Objects anywhere a method expects an
207`Iterable` with no performance penalty.
208
209```javascript
210var map1 = Immutable.Map({a:1, b:2, c:3, d:4});
211var map2 = Immutable.Map({c:10, a:20, t:30});
212var obj = {d:100, o:200, g:300};
213var map3 = map1.merge(map2, obj);
214// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
215```
216
217This is possible because `immutable` can treat any JavaScript Array or Object
218as an Iterable. You can take advantage of this in order to get sophisticated
219collection methods on JavaScript Objects, which otherwise have a very sparse
220native API. Because Seq evaluates lazily and does not cache intermediate
221results, these operations can be extremely efficient.
222
223```javascript
224var myObject = {a:1,b:2,c:3};
225Immutable.Seq(myObject).map(x => x * x).toObject();
226// { a: 1, b: 4, c: 9 }
227```
228
229Keep in mind, when using JS objects to construct Immutable Maps, that
230JavaScript Object properties are always strings, even if written in a quote-less
231shorthand, while Immutable Maps accept keys of any type.
232
233```js
234var obj = { 1: "one" };
235Object.keys(obj); // [ "1" ]
236obj["1"]; // "one"
237obj[1]; // "one"
238
239var map = Immutable.fromJS(obj);
240map.get("1"); // "one"
241map.get(1); // undefined
242```
243
244Property access for JavaScript Objects first converts the key to a string, but
245since Immutable Map keys can be of any type the argument to `get()` is
246not altered.
247
248
249### Converts back to raw JavaScript objects.
250
251All `immutable` Iterables can be converted to plain JavaScript Arrays and
252Objects shallowly with `toArray()` and `toObject()` or deeply with `toJS()`.
253All Immutable Iterables also implement `toJSON()` allowing them to be passed to
254`JSON.stringify` directly.
255
256```javascript
257var deep = Immutable.Map({ a: 1, b: 2, c: Immutable.List.of(3, 4, 5) });
258deep.toObject() // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
259deep.toArray() // [ 1, 2, List [ 3, 4, 5 ] ]
260deep.toJS() // { a: 1, b: 2, c: [ 3, 4, 5 ] }
261JSON.stringify(deep) // '{"a":1,"b":2,"c":[3,4,5]}'
262```
263
264### Embraces ES6
265
266`Immutable` takes advantage of features added to JavaScript in [ES6][],
267the latest standard version of ECMAScript (JavaScript), including [Iterators][],
268[Arrow Functions][], [Classes][], and [Modules][]. It's also inspired by the
269[Map][] and [Set][] collections added to ES6. The library is "transpiled" to ES3
270in order to support all modern browsers.
271
272All examples are presented in ES6. To run in all browsers, they need to be
273translated to ES3.
274
275```js
276// ES6
277foo.map(x => x * x);
278// ES3
279foo.map(function (x) { return x * x; });
280```
281
282[Iterators]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
283[Arrow Functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
284[Classes]: http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
285[Modules]: http://www.2ality.com/2014/09/es6-modules-final.html
286
287
288Nested Structures
289-----------------
290
291The collections in `immutable` are intended to be nested, allowing for deep
292trees of data, similar to JSON.
293
294```javascript
295var nested = Immutable.fromJS({a:{b:{c:[3,4,5]}}});
296// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }
297```
298
299A few power-tools allow for reading and operating on nested data. The
300most useful are `mergeDeep`, `getIn`, `setIn`, and `updateIn`, found on `List`,
301`Map` and `OrderedMap`.
302
303```javascript
304var nested2 = nested.mergeDeep({a:{b:{d:6}}});
305// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
306```
307
308```javascript
309nested2.getIn(['a', 'b', 'd']); // 6
310
311var nested3 = nested2.updateIn(['a', 'b', 'd'], value => value + 1);
312// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
313
314var nested4 = nested3.updateIn(['a', 'b', 'c'], list => list.push(6));
315// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
316```
317
318
319Lazy Seq
320--------
321
322`Seq` describes a lazy operation, allowing them to efficiently chain
323use of all the Iterable methods (such as `map` and `filter`).
324
325**Seq is immutable** — Once a Seq is created, it cannot be
326changed, appended to, rearranged or otherwise modified. Instead, any mutative
327method called on a Seq will return a new Seq.
328
329**Seq is lazy** — Seq does as little work as necessary to respond to any
330method call.
331
332For example, the following does not perform any work, because the resulting
333Seq is never used:
334
335 var oddSquares = Immutable.Seq.of(1,2,3,4,5,6,7,8)
336 .filter(x => x % 2).map(x => x * x);
337
338Once the Seq is used, it performs only the work necessary. In this
339example, no intermediate arrays are ever created, filter is called three times,
340and map is only called twice:
341
342 console.log(oddSquares.get(1)); // 9
343
344Any collection can be converted to a lazy Seq with `.toSeq()`.
345
346 var seq = Immutable.Map({a:1, b:1, c:1}).toSeq();
347
348Seq allow for the efficient chaining of sequence operations, especially when
349converting to a different concrete type (such as to a JS object):
350
351 seq.flip().map(key => key.toUpperCase()).flip().toObject();
352 // Map { A: 1, B: 1, C: 1 }
353
354As well as expressing logic that would otherwise seem memory-limited:
355
356 Immutable.Range(1, Infinity)
357 .skip(1000)
358 .map(n => -n)
359 .filter(n => n % 2 === 0)
360 .take(2)
361 .reduce((r, n) => r * n, 1);
362 // 1006008
363
364Note: An iterable is always iterated in the same order, however that order may
365not always be well defined, as is the case for the `Map`.
366
367
368Equality treats Collections as Data
369-----------------------------------
370
371`Immutable` provides equality which treats immutable data structures as pure
372data, performing a deep equality check if necessary.
373
374```javascript
375var map1 = Immutable.Map({a:1, b:1, c:1});
376var map2 = Immutable.Map({a:1, b:1, c:1});
377assert(map1 !== map2); // two different instances
378assert(Immutable.is(map1, map2)); // have equivalent values
379assert(map1.equals(map2)); // alternatively use the equals method
380```
381
382`Immutable.is()` uses the same measure of equality as [Object.is][]
383including if both are immutable and all keys and values are equal
384using the same measure of equality.
385
386[Object.is]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
387
388
389Batching Mutations
390------------------
391
392> If a tree falls in the woods, does it make a sound?
393>
394> If a pure function mutates some local data in order to produce an immutable
395> return value, is that ok?
396>
397> — Rich Hickey, Clojure
398
399Applying a mutation to create a new immutable object results in some overhead,
400which can add up to a minor performance penalty. If you need to apply a series
401of mutations locally before returning, `Immutable` gives you the ability to
402create a temporary mutable (transient) copy of a collection and apply a batch of
403mutations in a performant manner by using `withMutations`. In fact, this is
404exactly how `Immutable` applies complex mutations itself.
405
406As an example, building `list2` results in the creation of 1, not 3, new
407immutable Lists.
408
409```javascript
410var list1 = Immutable.List.of(1,2,3);
411var list2 = list1.withMutations(function (list) {
412 list.push(4).push(5).push(6);
413});
414assert(list1.size === 3);
415assert(list2.size === 6);
416```
417
418Note: `immutable` also provides `asMutable` and `asImmutable`, but only
419encourages their use when `withMutations` will not suffice. Use caution to not
420return a mutable copy, which could result in undesired behavior.
421
422*Important!*: Only a select few methods can be used in `withMutations` including
423`set`, `push` and `pop`. These methods can be applied directly against a
424persistent data-structure where other methods like `map`, `filter`, `sort`,
425and `splice` will always return new immutable data-structures and never mutate
426a mutable collection.
427
428
429Documentation
430-------------
431
432[Read the docs](http://facebook.github.io/immutable-js/docs/) and eat your vegetables.
433
434Docs are automatically generated from [Immutable.d.ts](https://github.com/facebook/immutable-js/blob/master/type-definitions/Immutable.d.ts).
435Please contribute!
436
437Also, don't miss the [Wiki](https://github.com/facebook/immutable-js/wiki) which
438contains articles on specific topics. Can't find something? Open an [issue](https://github.com/facebook/immutable-js/issues).
439
440
441Testing
442-------
443
444If you are using the [Chai Assertion Library](http://chaijs.com/), [Chai Immutable](https://github.com/astorije/chai-immutable) provides a set of assertions to use against `Immutable` collections.
445
446
447Contribution
448------------
449
450Use [Github issues](https://github.com/facebook/immutable-js/issues) for requests.
451
452We actively welcome pull requests, learn how to [contribute](./CONTRIBUTING.md).
453
454
455Changelog
456---------
457
458Changes are tracked as [Github releases](https://github.com/facebook/immutable-js/releases).
459
460
461Thanks
462------
463
464[Phil Bagwell](https://www.youtube.com/watch?v=K2NYwP90bNs), for his inspiration
465and research in persistent data structures.
466
467[Hugh Jackson](https://github.com/hughfdjackson/), for providing the npm package
468name. If you're looking for his unsupported package, see [this repository](https://github.com/hughfdjackson/immutable).
469
470
471License
472-------
473
474Immutable.js is [MIT-licensed](https://github.com/facebook/immutable-js/blob/master/LICENSE).
Note: See TracBrowser for help on using the repository browser.