可変オブジェクト
JavaScriptでは、オブジェクトは参照型データです。利点は、オブジェクトが頻繁に変更されると、元のオブジェクトに基づいて変更され、再作成する必要がないことです。これは、メモリを効果的に利用することができ、メモリスペースの無駄を引き起こすことはありません。オブジェクトのこの特性は、中国語では「可変」を意味する、可変性と呼ばれる可能性があります。
可変オブジェクトの場合、その柔軟性と変化が不利な点になる場合があります。データが柔軟で変化しやすいほど、制御が難しくなります。複雑な構造を持つオブジェクトの場合、データは誤って不注意に変更されます。オブジェクトが複数のスコープで使用されている場合、データが変更されるかどうかを予測することは困難です。
var obj = {/*複雑な構造を持つオブジェクト*/}; dosomething(obj); //上記の関数線が終了した後、OBJはまだ元のOBJですか?この問題に対処するために、従来のソリューションは、オブジェクトを深くコピーして新しいオブジェクトに変更することにより、新しいオブジェクトをコピーできます。これにより、データの制御可能性が確保されますが、頻繁にコピーすることでメモリスペースの無駄が大幅に発生します。
var obj = {/*複雑な構造を持つオブジェクト*/}; //コピーは新しいobj2 //を作成しますが、コピー操作はvar obj2 = deepclone(obj); dosomething(obj2); //上記の関数が終了した後、OBJ2が終了した後、OBJが間違いなく元のOBJになることは間違いなく終了します。不変のオブジェクト
上記の問題をよりよく解決するために、文字通り中国語に翻訳された「不変」である不変のオブジェクトが現れます。不変のオブジェクトが変更されるたびに、新しい不変のオブジェクトが作成されます。新しいオブジェクトの操作は、元のオブジェクトのデータに影響しません。この特別なオブジェクトは、JavaScriptの新しい機能的機能ではなく、この問題を解決するために業界が提供する一連のソリューションです。いくつかの優れたオープンソースライブラリが登場しました。その中で最も有名なのは、FacebookのLee ByronのオープンソースImmutable.jsです。もちろん、Immutableのソリューションはオリジナルではありませんが、ClojureとScalaからのものです。
可変性と不変のパフォーマンス比較
可変オブジェクトの非効率的な動作は、主に複製と比較に反映されており、不変のオブジェクトはこれら2つの非効率的な問題点を解決します。
通常の可変オブジェクトのディープコピー操作は、データ全体をコピーします。不変のオブジェクトは、データを変更するときにデータ全体をコピーするのではなく、リンクリストの構造と同様に、変更されたノードと未変化ノードの間の親子関係を新しいノードに転送します。 「コピー」の観点から見ると、複製の最小化が達成され、変更されていない部分が共有されます。コピー時には可変は「フル」ですが、不変は「増分」であり、メモリスペースの高いまたは低い使用率を決定します。
また、不変のオブジェクトが変更されるたびに、新しい不変のオブジェクトが作成される機能に基づいています。これにより、データの変更された状態を一連のスナップショットに保存できますが、これも非常に便利です。
比較操作について話しましょう。可変オブジェクトの場合、2つのオブジェクトが等しいかどうかを比較する場合は、比較のためにオブジェクトの各ノードを通過する必要があります。複雑な構造を持つオブジェクトの場合、それらの効率は間違いなくそれほど高くありません。不変のオブジェクトの場合、Immutable.jsは、2つの不変のオブジェクトの「値」が等しいかどうかを直接決定するAPIを提供します。
var map1 = inmutable.map({a:1、b:1、c:1}); var map2 = inmutable.map({a:1、b:1、c:1}); assert(map1!== map2); //異なる不変のインスタンス、参照アドレスはアサート(Immutable.is(Map1、Map2)); // map1とmap2の値は等しく、値はassert(map1.equals(map2)); //不変の関数は同じです実際の開発アプリケーションでは、パフォーマンスが常に最も重要で重要であるとは限りません。通常のJavaScriptプロジェクトでは、不変の特性によって提起されたデータの制御可能性は、パフォーマンスよりも有利です。可変オブジェクトの場合、閉じたスコープでの使用に適していますが、データを複数のスコープに渡す必要がある場合に不変のオブジェクトは使用するのに適しています。
可変性と不変の違い
Immutable.jsは、さまざまなImutableデータ構造を提供します。リストスタックマップを含むOrderedMap Set orderedSetレコードを含みます。
ここでは、各データ構造の使用については説明しませんが、主に不変のオブジェクトの使用と可変オブジェクトの使用の違いについて話します。
ネイティブの可変オブジェクトは、「読み取り」と「執筆」に非常に便利です。
var mutableobj = {}; // data data mutableobj.foo = 'bar'; // read data console.log(mutableobj.foo);不変のオブジェクトは、セットを介してデータを「読み取り」、「書き込む」必要があります。
var ImmutableObj1 = Immutable.map(); // write data var immutabableobj2 = immutableobj1.set( 'foo'、 'bar'); // read data console.log(mutableobj2.get( 'foo')); // => 'bar'
設定方法の使用を説明するために、上記の例は最初に空のオブジェクトを作成しました。実際、インスタンス化中に初期値を渡すことができます。
var immutableobj = Immutable.map({'foo'、 'bar'});より深いレベルのデータの場合、Immutable.jsが提供するアクセスインターフェイスは非常に便利です。
var immutableobj1 = inmutable.fromjs({a:{b: 'c'}、d:[1、2、3]}); //ディープデータconsole.log(inmutableobj1.getin(['a'、 'b'])); // => 'c'Console.log(Immutableobj1.getin([' a '、' b '])); // => 2 //ディープデータの変更var immutableobj2 = inmutableobj1.setin(['a'、 'b']、 'd'); console.log(mutableobj2.getin(['a'、 'b'])); // => 'd'ネイティブの可変オブジェクトの場合、チェーン内の深いレベルのデータにアクセスするときに未定義のエラーが報告される場合がありますが、不変のオブジェクトはこの状況に遭遇したときにエラーを報告せず、リターンは未定義です。
デバッグするときは、不変のオブジェクトの内部構造を表示する場合は、tojson()を使用して最初に通常の可変オブジェクトに変換することをお勧めします。