2015-08-09 13 views
32

Niezmienne obiekt może być przypadek:Jak sprawdzić, czy obiekt jest niezmienny?

  • Immutable.List
  • Immutable.Map
  • Immutable.OrderedMap
  • Immutable.Set
  • Immutable.OrderedSet
  • Immutable.Stack
+0

Przyjmuję, że jest bardziej przyjazne dla użytkownika podejście niż wykonanie 'instanceof' dla każdego typu. – Gajus

Odpowiedz

36

Istnieje otwarty bilet na numer improve the API, który znajduje się na mapie drogowej 4.0. Dopóki to nie zostanie zaimplementowane, sugeruję użycie Immutable.Iterable.isIterable() (docs).

Korzystanie instanceof jest not reliable (np zwraca false gdy różne moduły wykorzystują różne kopie Immutable.js)

16

Dowiedziałem się, że using instanceof to determine wether object is Immutable jest niebezpieczna:

Moduł A:

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

Moduł B:

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

Immutable.js API definiuje następujące metody, aby sprawdzić czy przedmiot jest wystąpienie niezmienny:

i

Te ostatnie sprawdza czy:

prawda, jeśli iterable, lub któregokolwiek z jej podklasy.

List, Stack, Map, OrderedMap, Set i OrderedSet są wszystkie podklasy Iterable.

1

I w ten sposób można poznać, jaki typ zmiennej Niezmienne iterowalny jest:

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>

0

Sprawdzanie konkretne typy ogólnie spowoduje więcej pracy później. Zwykle czekałbym na zablokowanie typów poprzez zaznaczenie mapy lub listy, ale ...

Moja motywacja polega głównie na tym, że moje wezwanie .get nieokreślonych poops się bardzo trudne, i inicjowanie prawidłowo w każdym miejscu pomaga, ale nie łapie wszystkich skrajnych przypadków. Chcę tylko dane lub nieokreślone bez żadnych uszkodzeń. Określone sprawdzanie typów powoduje, że wykonuję więcej pracy później, jeśli chcę wprowadzić zmiany.

Ta luźniejsza wersja rozwiązuje znacznie więcej przypadków krawędzi (większość, jeśli nie wszystkie, rozszerzenia typu Iterable, które ma .get, i wszystkie dane są ostatecznie zdobyte) niż konkretny typ sprawdza (który zwykle oszczędza tylko przy próbie aktualizacji) niewłaściwy typ itp.).

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

Po prostu daj mi to, o co Cię proszę, lub powiedz, że nie. Nie wybuchaj. Uważam, że podkreślenie robi coś podobnego.

11

Immutable.js już isImmutable() funkcję:

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

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

To nie jest dostępne w 3.8.1 – danday74

+0

Ktoś wie, jak wyświetlić dokumenty API dla poprzednich wersji na ich oficjalnej stronie internetowej? – Romasato

0

To może działać w niektórych przypadkach:

typeof object.toJS === 'function' 

Można użyć tej metody Duck Typing sprawdzając niezmienne vs obiektów Węgierska (json) na przykład.

+1

Dlaczego nie? Proszę skomentuj. –

Powiązane problemy