Baike.dev
All toolsTrendingOpen sourceNewsSubmit
Log in
< 返回工具列表
I

immutable-js

> 编程语言
开源

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

33.0K stars0 点赞1 次浏览
访问官网GitHub

工具介绍

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

Immutable collections for JavaScript

Chat on slack

Read the docs and eat your vegetables.

Docs are automatically generated from [README.md][] and [immutable.d.ts][]. Please contribute! Also, don't miss the [wiki][] which contains articles on additional specific topics. Can't find something? Open an [issue][].

Table of contents:

  • Introduction
  • Getting started
  • The case for Immutability
  • JavaScript-first API
  • Nested Structures
  • Equality treats Collections as Values
  • Batching Mutations
  • Lazy Seq
  • Additional Tools and Resources
  • Contributing

Introduction

[Immutable][] data cannot be changed once created, leading to much simpler application development, no defensive copying, and enabling advanced memoization and change detection techniques with simple logic. [Persistent][] data presents a mutative API which does not update the data in-place, but instead always yields new updated data.

Immutable.js provides many Persistent Immutable data structures including: List, Stack, Map, OrderedMap, Set, OrderedSet and Record.

These data structures are highly efficient on modern JavaScript VMs by using structural sharing via [hash maps tries][] and [vector tries][] as popularized by Clojure and Scala, minimizing the need to copy or cache data.

Immutable.js also provides a lazy Seq, allowing efficient chaining of collection methods like map and filter without creating intermediate representations. Create some Seq with Range and Repeat.

Want to hear more? Watch the presentation about Immutable.js: [README.md]: https://github.com/immutable-js/immutable-js/blob/main/README.md [immutable.d.ts]: https://github.com/immutable-js/immutable-js/blob/main/type-definitions/immutable.d.ts [wiki]: https://github.com/immutable-js/immutable-js/wiki [issue]: https://github.com/immutable-js/immutable-js/issues [Persistent]: https://en.wikipedia.org/wiki/Persistent_data_structure [Immutable]: https://en.wikipedia.org/wiki/Immutable_object [hash maps tries]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie [vector tries]: https://hypirion.com/musings/understanding-persistent-vector-pt-1

Getting started

Install immutable using npm.

# using npm
npm install immutable

# using Yarn
yarn add immutable

# using pnpm
pnpm add immutable

# using Bun
bun add immutable

Then require it into any module.

import { Map } from 'immutable';
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 50);
map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50

Browser

Immutable.js has no dependencies, which makes it predictable to include in a Browser.

It's highly recommended to use a module bundler like webpack, rollup, or browserify. The immutable npm module works without any additional consideration. All examples throughout the documentation will assume use of this kind of tool.

Alternatively, Immutable.js may be directly included as a script tag. Download or link to a CDN such as CDNJS or jsDelivr.

Use a script tag to directly add Immutable to the global scope:

<script src="immutable.min.js"></script>
<script>
  var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
  var map2 = map1.set('b', 50);
  map1.get('b'); // 2
  map2.get('b'); // 50
</script>

Or use an AMD-style loader (such as RequireJS):

require(['./immutable.min.js'], function (Immutable) {
  var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
  var map2 = map1.set('b', 50);
  map1.get('b'); // 2
  map2.get('b'); // 50
});

Flow & TypeScript

Use these Immutable collections and sequences as you would use native collections in your Flowtype or TypeScript programs while still taking advantage of type generics, error detection, and auto-complete in your IDE.

Installing immutable via npm brings with it type definitions for Flow (v0.55.0 or higher) and TypeScript (v4.5 or higher), so you shouldn't need to do anything at all!

Using TypeScript with Immutable.js v4+

Immutable.js type definitions embrace ES2015. While Immutable.js itself supports legacy browsers and environments, its type definitions require TypeScript's 2015 lib. Include either "target": "es2015" or "lib": "es2015" in your tsconfig.json, or provide --target es2015 or --lib es2015 to the tsc command.

import { Map } from 'immutable';
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 50);
map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50

Using TypeScript with Immutable.js v3 and earlier:

Previous versions of Immutable.js include a reference file which you can include via relative path to the type definitions at the top of your file.

///<reference path='./node_modules/immutable/dist/immutable.d.ts'/>
import { Map } from 'immutable';
var map1: Map<string, number>;
map1 = Map({ a: 1, b: 2, c: 3 });
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50

The case for Immutability

Much of what makes application development difficult is tracking mutation and maintaining state. Developing with immutable data encourages you to think differently about how data flows through your application.

Subscribing to data events throughout your application creates a huge overhead of book-keeping which can hurt performance, sometimes dramatically, and creates opportunities for areas of your application to get out of sync with each other due to easy to make programmer error. Since immutable data never changes, subscribing to changes throughout the model is a dead-end and new data can only ever be passed from above.

This model of data flow aligns well with the architecture of React and especially well with an application designed using the ideas of Flux.

When data is passed from above rather than being subscribed to, and you're only interested in doing work when something has changed, you can use equality.

Immutable collections should be treated as values rather than objects. While objects represent some thing which could change over time, a value represents the state of that thing at a particular instance of time. This principle is most important to understanding the appropriate use of immutable data. In order to treat Immutable.js collections as values, it's important to use the Immutable.is() function or .equals() method to determine value equality instead of the === operator which determines object reference identity.

import { Map } from 'immutable';
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = Map({ a: 1, b: 2, c: 3 });
map1.equals(map2); // true
map1 === map2; // false

Note: As a performance optimization Immutable.js attempts to return the existing collection when an operation would result in an identical collection, allowing for using === reference equality to determine if something definitely has not changed. This can be extremely useful when used within a memoization function which would prefer to re-run the function if a deeper equality check could potentially be more costly. The === equality check is also used internally by Immutable.is and .equals() as a performance optimization.

import { Map } from 'immutable';
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 2); // Set to same value
map1 === map2; // true

If an object is immutable, it can be "copied" simply by making another reference to it instead of copying the entire object. Because a reference is much smaller than the object itself, this results in memory savings and a potential boost in execution speed for programs which rely on copies (such as an undo-stack).

import { Map } from 'immutable';
const map = Map({ a: 1, b: 2, c: 3 });
const mapCopy = map; // Look, "copies" are free!

JavaScript-first API

While Immutable.js is inspired by Clojure, Scala, Haskell and other functional programming environments, it's designed to bring these powerful concepts to JavaScript, and therefore has an Object-Oriented API that closely mirrors that of ES2015 Array, Map, and Set.

The difference for the immutable collections is that methods which would mutate the collection, like push, set, unshift or splice, instead return a new immutable collection. Methods which return new arrays, like slice or concat, instead return new immutable collections.

import { List } from 'immutable';
const list1 = List([1, 2]);
const list2 = list1.push(3, 4, 5);
const list3 = list2.unshift(0);
const list4 = list1.concat(list2, list3);
assert.equal(list1.size, 2);
assert.equal(list2.size, 5);
assert.equal(list3.size, 6);
assert.equal(list4.size, 13);
assert.equal(list4.get(0), 1);

Almost all of the methods on Array will be found in similar form on Immutable.List, those of Map found on Immutable.Map, and those of Set found on Immutable.Set, including collection operations like forEach() and map().

import { Map } from 'immutable';
const alpha = Map({ a: 1, b: 2, c: 3, d: 4 });
alpha.map((v, k) => k.toUpperCase()).join();
// 'A,B,C,D'

Convert from raw JavaScript objects and arrays.

Designed to inter-operate with your existing JavaScript, Immutable.js accepts plain JavaScript Arrays and Objects anywhere a method expects a Collection.

import { Map, List } from 'immutable';
const map1 = Map({ a: 1, b: 2, c: 3, d: 4 });
const map2 = Map({ c: 10, a: 20, t: 30 });
const obj = { d: 100, o: 200, g: 300 };
const map3 = map1.merge(map2, obj);
// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
const list1 = List([1, 2, 3]);
const list2 = List([4, 5, 6]);
const array = [7, 8, 9];
const list3 = list1.concat(list2, array);
// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

This is possible because Immutable.js can treat any JavaScript Array or Object as a Collection. You can take advantage of this in order to get sophisticated collection methods on JavaScript Objects, which otherwise have a very sparse native API. Because Seq evaluates lazily and does not cache intermediate results, these operations can be extremely efficient.

import { Seq } from 'immutable';
const myObject = { a: 1, b: 2, c: 3 };
Seq(myObject)
  .map((x) => x * x)
  .toObject();
// { a: 1, b: 4, c: 9 }

Keep in mind, when using JS objects to construct Immutable Maps, that JavaScript Object properties are always strings, even if written in a quote-less shorthand, while Immutable Maps accept keys of any type.

import { fromJS } from 'immutable';

const obj = { 1: 'one' };
console.log(Object.keys(obj)); // [ "1" ]
console.log(obj['1'], obj[1]); // "one", "one"

const map = fromJS(obj);
console.log(map.get('1'), map.get(1)); // "one", undefined

Property access for JavaScript Objects first converts the key to a string, but since Immutable Map keys can be of any type the argument to get() is not altered.

Converts back to raw JavaScript objects.

All Immutable.js Collections can be converted

核心特点

  • •Introduction
  • •Getting started
  • •The case for Immutability
  • •JavaScript-first API
  • •Nested Structures
  • •Equality treats Collections as Values
  • •Batching Mutations
  • •Lazy Seq
  • •Additional Tools and Resources
  • •Contributing

> 标签

TypeScript

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月9日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言