如何检查对象是否是不可变的?

时间:2015-08-09 18:26:41

标签: immutable.js

不可变对象可以是:

的实例
  • Immutable.List
  • Immutable.Map
  • Immutable.OrderedMap
  • Immutable.Set
  • Immutable.OrderedSet
  • Immutable.Stack

6 个答案:

答案 0 :(得分:41)

有一张开放的improve the API门票,位于4.0的路线图上。在此实施之前,我建议您使用Immutable.Iterable.isIterable()docs)。

使用instanceofnot reliable(例如,当不同的模块使用不同的Immutable.js副本时返回false)

答案 1 :(得分:23)

我了解到using instanceof to determine wether object is Immutable不安全:

模块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。

ListStackMapOrderedMapSetOrderedSet都是Iterable的子类。

答案 2 :(得分:16)

自p4.0.0-rc.1以来,

Immutable.js具有isImmutable()功能:

 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:

 Immutable.Iterable.isIterable(YOUR_ENTITY)

因为所有不可变的都继承自Iterable对象

答案 3 :(得分:1)

这样你就可以知道什么类型的Immutable Iterable变量:

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>

答案 4 :(得分:0)

检查特定类型通常会在以后引起更多工作。通常我会等到通过检查Map或List来锁定类型,但是......

我的动机主要是我的调用.get of undefined poops本身非常难,并且在整个地方正确初始化有帮助,但没有捕获所有边缘情况。我只想要数据或未定义而没有任何破损。如果我希望它进行更改,特定类型检查会导致我以后做更多工作。

这个更宽松的版本解决了更多的边缘情况(大多数,如果不是所有的扩展类型Iterable都有.get,并且所有数据最终都得到了),而不是特定的类型检查(当你尝试更新时,它通常只会保存你)错误的类型等)。

/* 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
  }
}

请告诉我我的要求或告诉我不。不要爆炸。我相信下划线也有类似之处。

答案 5 :(得分:-1)

这可能在某些情况下有效:

typeof object.toJS === 'function'

例如,如果检查不可变vs普通对象(json),则可以使用此ducktyping方法。