Как проверить, является ли объект неизменным?

236
22

Непрерывный объект может быть экземпляром:


    Immutable.List
    Immutable.Map
    Immutable.OrderedMap
    Immutable.Set
    Immutable.OrderedSet
    Immutable.Stack

спросил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
1
Решение
256

Существует открытый билет улучшить API, который находится в дорожной карте для 4.0. Пока это не будет реализовано, я предлагаю вам использовать Immutable.Iterable.isIterable() (docs).

Использование instanceof не является надежным (например, возвращает false, когда разные модули используют разные копии Immutable.js)

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
170

Я узнал, что с использованием instanceof для определения того, что объект Immherable небезопасен, небезопасен:


Модуль 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

API-интерфейс Immutable.js определяет следующие методы проверки того, является ли объект экземпляром Immutable:

и


Последний проверяет, есть ли:


Истинно, если Iterable или любой из его подклассов.



List, Stack, Map, OrderedMap, Set и OrderedSet - все подклассы Iterable.

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
124

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

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
64

И таким образом вы можете узнать, какой тип неизменяемой переменной 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>

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
46

Это может работать в некоторых случаях:


typeof object.toJS === 'function'

Вы можете использовать этот метод ducktyping, если вы, например, проверяете неизменяемые vs простые объекты (json).

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
45

Проверка определенных типов обычно приведет к дополнительной работе. Обычно я бы подождал, чтобы заблокировать типы, проверив Карты или Список, но...


Моя мотивация здесь в основном заключается в том, что мой вызов .get из undefined сильно утомится, и правильная инициализация по всему месту помогает, но не захватывает все крайние случаи. Мне просто нужны данные или undefined без поломки. Специфическая проверка типов заставляет меня делать больше работы позже, если я хочу, чтобы она вносила изменения.


Эта более свободная версия решает много других случаев с краями (большинство, если не все, расширяют тип 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 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
}
}


Просто дай мне то, что я прошу, или скажи мне. Не взорваться. Я считаю, что подчеркивание также делает что-то подобное.

ответил(а) 2021-01-25T19:07:02+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема