web-dev-qa-db-ja.com

オブジェクトが不変かどうかを確認する方法は?

不変オブジェクトは、次のインスタンスになります。

  • Immutable.List
  • Immutable.Map
  • Immutable.OrderedMap
  • Immutable.Set
  • Immutable.OrderedSet
  • Immutable.Stack
42
Gajus

4.0のロードマップにある APIの改善 へのオープンチケットがあります。これが実装されるまで、Immutable.Iterable.isIterable()docs )を使用することをお勧めします。

instanceofの使用は 信頼できない です(たとえば、異なるモジュールが異なるImmutable.jsのコピーを使用する場合にfalseを返します)

41
mbh

instanceofを使用してオブジェクトが不変かどうかを判断する は安全でないことを学びました。

モジュールA:

var Immutable = require('immutable');
module.exports = Immutable.Map({foo: "bar});

モジュールB:

var Immutable = require('immutable');
var moduleA = require('moduleA');
moduleA instanceof Immutable.Map // will return false

Immutable.js APIは、オブジェクトがImmutableのインスタンスであるかどうかを確認する次のメソッドを定義します。

そして

後者は以下をチェックします:

Iterableまたはそのサブクラスの場合はTrue。

ListStackMapOrderedMapSet、およびOrderedSetはすべてIterableのサブクラスです。

23
Gajus

Immutable.jsには isImmutable() v4.0.0-rc.1以降の機能があります:

 import { isImmutable, Map, List, Stack } from 'immutable';

 isImmutable([]); // false
 isImmutable({}); // false
 isImmutable(Map()); // true
 isImmutable(List()); // true
 isImmutable(Stack()); // true
 isImmutable(Map().asMutable()); // false

以前のバージョンのいずれかを使用している場合、この方法でオブジェクトが不変かどうかを確認できます。

 Immutable.Iterable.isIterable(YOUR_ENTITY)

すべての不変はIterableオブジェクトから継承するため

17
Anton Novik

そして、このようにして、不変の反復可能な変数のタイプを知ることができます:

const obj0 = 'xxx';
const obj1 = Immutable.fromJS({x: 'XXX', z: 'ZZZ'});
const obj2 = Immutable.fromJS([ {x: 'XXX'}, {z: 'ZZZ'}]);

const types = ['List', 'Stack', 'Map', 'OrderedMap', 'Set', 'OrderedSet'];
const type0 = types.find(currType => Immutable[currType][`is${currType}`](obj0));
const type1 = types.find(currType => Immutable[currType][`is${currType}`](obj1));
const type2 = types.find(currType => Immutable[currType][`is${currType}`](obj2));

console.log(`Obj0 is: ${type0}`); // Obj0 is: undefined
console.log(`Obj1 is: ${type1}`); // Obj1 is: Map
console.log(`Obj2 is: ${type2}`); // Obj2 is: List
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
1
webmato

これはいくつかの場合に機能するかもしれません:

typeof object.toJS === 'function'

たとえば、不変オブジェクトとプレーンオブジェクト(json)をチェックする場合、このダックタイピングメソッドを使用できます。

0
Dan K.K.

一般に、特定のタイプをチェックすると、後により多くの作業が発生します。通常、MapまたはListをチェックしてタイプをロックインするのを待ちますが、...

ここでの私の動機は、主に未定義のうんちの呼び出し自体が非常に難しいことであり、あらゆる場所で適切に初期化することは役立ちますが、すべてのエッジケースをキャッチするわけではありません。破損することなく、データまたは未定義が必要です。特定の型チェックを使用すると、後で変更したい場合に、さらに作業を行うことができます。

この緩いバージョンは、特定のタイプチェックが行うよりも多くのEdgeケース(.getを持つすべての拡張型Iterableではなく、最終的にすべてのデータが取得されます)を解決します(通常、間違った型などで更新しようとしたときにのみ保存されます) )。

/* getValid: Checks for valid ImmutableJS type Iterable

    returns valid Iterable, valid Iterable child data, or undefined

    Iterable.isIterable(maybeIterable) && maybeIterable.get(['data', key], Map()), becomes
    getValid(maybeIterable, ['data', key], Map())

    But wait! There's more! As a result:
    getValid(maybeIterable) returns the maybeIterable or undefined 
    and we can still say getValid(maybeIterable, null, Map()) returns the maybeIterable or Map()            */

export const getValid = (maybeIterable, path, getInstead) =>
  Iterable.isIterable(maybeIterable) && path
    ? ((typeof path === 'object' && maybeIterable.getIn(path, getInstead)) || maybeIterable.get(path, getInstead))
    : Iterable.isIterable(maybeIterable) && maybeIterable || getInstead;


//Here is an untested version that a friend requested. It is slightly easier to grok.

export const getValid = (maybeIterable, path, getInstead) => {
  if(valid(maybeIterable)) {                 // Check if it is valid
    if(path) {                                        // Check if it has a key
      if(typeof path === 'object') {     // Check if it is an 'array'
        return maybeIterable.getIn(path, getInstead) // Get your stuff
      } else {
        maybeIterable.get(path, getInstead)          // Get your stuff
      }
    } else {
      return maybeIterable || getInstead;                 // No key? just return the valid Iterable
    }
  } else {
    return undefined;                       // Not valid, return undefined, perhaps should return false here
  }
}

私が求めていることを教えてください。爆発しないでください。アンダースコアも同様のことをしていると思います。

0
Urasquirrel