Facebook製 JavaScript 関数ライブラリ。Immutable.js がいい感じ!
2016.07.31
この記事は最終更新日から1年以上が経過しています。
お久しぶりにJavaScriptの話題でもと。
Facebook製 JavaScriptライブラリ(フレームワーク)と言えば、React.jsなイメージですが、
こちらも結構前にリリースされていて、あまり触ってこなかったので今回はこちらを。
immutable
公式サイト
http://facebook.github.io/immutable-js/
github
https://github.com/facebook/immutable-js
Immutable collections for JavaScript
immutable.jsはその名の通りimmutable(不変)なコレクションを提供するJavaScriptライブラリとなっております。
そう、JavaScriptオブジェクトは基本、mutableなオブジェクトな訳で、それをimmutableなオブジェクトへと変換してくれるのです。
オブジェクトをimmutableにする事によって、関数型プログラミングで用いられる、永続データプログラミングを行う事ができます。
これを利用する事によって、関数型プログラミングの強い後押しをしてくれ、参照透過性の高いプログラミングが行えますね。
これは良い!
githubのスター数もかなりの数を行っておりますね。
さぞかしみんなも使っているのだろうと、プログラミング共有サービスで有名な「Qiita」を覗いてみると、
あまり投稿がない感じですね。。日本の記事も結構少ない気がしますね。。
JavaScriptを主に書かれている日本の方にはとっつきにくい概念なのですかね??
やはり、型を入れて利用していると、この辺はどうも欲しくなりますよね。
では、早速使っていきましょうー!
インストール
npmコマンドでインストールする際
$ npm install immutable
webBrowser で利用する場合はimmutable.jsファイルを読みこみましょう。
<script src="immutable.min.js"></script>
node環境では、requireして利用。
使い方
では早速、Map関数を利用。
Map
var Immutable = require("immutable"); var map1 = Immutable.Map({a: 1, b:2, c: 3});
Map()でオブジェクトをimmutableなオブジェクトに変換することが可能です。
勿論ですが、変換後こんな感じで参照することは出来ません。
console.log(map1.b); // undefined
キーが、”b”の値を取得する際は、「get」を使用します。
console.log(map1.get('b'));
これを変数に渡してみましょう。
通常だと、参照渡しで渡ってしまうのですが、値渡しすることが出来ます。
var Immutable = require("immutable"); var map1 = Immutable.Map({a: 1, b:2, c: 3}); var clone1 = map1; var clone2 = map1.set('b', 50); console.log(map1.get('b')); //2 console.log(clone1.get('b')); //2 console.log(clone2.get('b')); //50
assert(map1.equals(clone1) === true); assert(map1.equals(clone2) === false);
ふむ。素敵な感じですよね。
merge
その他、mergeを行い時にも至って簡単に行えます。
var x = Immutable.Map({a: 10, b: 20, c: 30}); var y = Immutable.Map({b: 40, a: 50, d: 60}); x.merge(y) // { a: 50, b: 40, c: 30, d: 60 } y.merge(x) // { b: 20, a: 10, d: 60, c: 30 }
その他にも、Map APIには、delete、clear、update、has、first、last、keys、values、reverse、sortBy、slice、flatten、reduce、max、some、join、count、find ….と必要そうなものは全て揃っている印象なので、安心して使えますね。
List
続いて、Listを軽く。
1,2,3が格納された配列を生成してみます。
var arr = [1,2,3]; arr.push(4); console.log(arr); // Array [1, 2, 3, 4]
ネイティブでは、このように破壊的メソッド(元のオブジェクトが壊されている状態。)で配列に代入されてしまいます。
このような場合でも、immutable.jsは力を発揮します。
immutable.jsでは List APIが用意されていますので、そちらを利用して配列を生成します。
[cod lang=”js”e]var arr = immutable.List.of(1, 2, 3);
arr.push(4);
console.log(arr.toJS());// Array[1, 2, 3][/code]
反映されていないのが確認できます。
変数に値渡しを行うことによって、非破壊的にpushを行う事ができます。
var arr = Immutable.List.of(1, 2, 3); var newArr = arr.push(4); console.log(arr.toJS()); //Array [1, 2, 3] console.log(newArr.toJS()); //Array [1, 2, 3, 4]
元のarrに影響がいってないことが確認できます。
その他、pop、unshift、shift、set、delete、clear… などのAPIも用意されております。
数を知りたい時は「size」を利用すればすぐに知れます。
console.log(arr.size); //4
fromJS()
JavaScript界隈では良く利用するファクトリーパターンで明示的に生成も行えますね。
fromJsonやfromDataなど、良く見かけますが、immutable.jsではfromJSとJavaScriptオブジェクトとの世界を切り分けているのを垣間見れます。
JSオブジェクトからの生成。
var obj = immutable.fromJS({a: 1, b: 2}); console.log(obj.get('a')); // 1
サンプルを見ると、callbackでListとOrderedMapにimmutableに変換しているのがわかりますね。
Immutable.fromJS({a: {b: [10, 20, 30]}, c: 40}, function (key, value) { var isIndexed = Immutable.Iterable.isIndexed(value); return isIndexed ? value.toList() : value.toOrderedMap(); }); // true, "b", {b: [10, 20, 30]} // false, "a", {a: {b: [10, 20, 30]}, c: 40} // false, "", {"": {a: {b: [10, 20, 30]}, c: 40}}
topレベルのkeyが空文字で変える様になっている様ですね。
JavaScriptオブジェクトに戻す際は、toJS()で戻すことが可能です。
console.log(obj.toJS()); // a: Object // b: Array [10, 20, 30] // C: 40
遅延評価
関数型プログラミングの特徴として、immutableな永続データプログラミング、イベント駆動、宣言型でコードは参照透過。
といった特徴があるかと思います。
immutable.jsも遅延評価を行っており「必要な時に必要な分処理される」設計となっております。
例に、自然数10までの配列を作成してみたいと思います。
var natural = Immutable.Range(); var natural_10 = natural.take(10); natural_10 = natural_10.toArray(); //Array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Range()で自然数を生成し、takeで数をしてします。
toArray()で配列で出力するのですが、この時に初めて処理が走ります。
このように、必要な時になった時に処理が走るように設計されております。
ちなみに上記の記述は以下のメソッドチェーンでも行う事が可能です。
var natural_10 = Immutable.Range().take(10).toArray(); //Array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
その他にも用意されてAPIは沢山あり、全部書こうとするとかなりの量となってしまいますので、その他は公式ドキュメントを確認していただければと思います。
公式ドキュメント
http://facebook.github.io/immutable-js/docs/#/
immutable-jsはReactJSとの相性もよさそうな感じで、関数型プログラミングを行うにはもってこいのライブラリですね。
関数型プログラミングを行っていて、JavaScriptに精通されている方に好まれている感じですかね。
ではではー。