不可变 JS 比较嵌套结构

Immutable JS compare nested structures

我有 2 个嵌套结构 newStatenewState1

但是当我比较它们时,equals() 或 Immutable.is() 返回 false。这些结构中的值相同。

如何正确比较newStatenewState1?

var grid = {
    editable: false,
    widgets: [{
        name: 'Some widget',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }, {
        name: 'Some widget1',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }]
};

var state = Immutable.fromJS(grid);

var newState = state.updateIn(['widgets'], function (list) {
    return list.push(Immutable.Map({
        name: 'Some widget2',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }));
});

var newState1 = state.updateIn(['widgets'], function (list) {
    return list.push(Immutable.Map({
        name: 'Some widget2',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }));
});

console.log(state.toJS(), newState.toJS(), newState1.toJS());

console.log(newState.equals(newState1)); //false

JSFiddle 中的代码: https://jsfiddle.net/z3xuagwm/

immutablejs好像没有做深度转换,所以如果你的value是object,就一直是object。

由于您在每个更新步骤中创建不同的对象,并且当您相互比较时,这些对象将被视为不同,因此您还应该将其转换为 Immutable.Map 对象,以便进行比较是的。

// Primitives.
var test1 = Immutable.Map({
    a: 'a', 
    b: 'b', 
    c: 'c'
});
var test2 = Immutable.Map({
    a: 'a',
    b: 'b',
    c: 'c'
});
console.log('Test primitive', test1.equals(test2)); // true

// Object
test1 = Immutable.Map({
    a: 'a',
    b: 'b',
    c: {}
});
test2 = Immutable.Map({
    a: 'a',
    b: 'b',
    c: {}
});
console.log('Test object', test1.equals(test2));  // false
// Its because
var a = {};
var b = {};
console.log('a === b?', a === b); // false

// Convert
test1 = Immutable.Map({
    a: 'a',
    b: 'b',
    c: Immutable.Map({})
});
test2 = Immutable.Map({
    a: 'a',
    b: 'b',
    c: Immutable.Map({})
});
console.log('Test converted', test1.equals(test2)); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.5/immutable.min.js"></script>

在推送函数中将 Immutable.Map 更改为 Immutable.fromJS(如前所述 - 只有 fromJS 会进行深度转换,Map、List 等不会):

var newState = state.updateIn(['widgets'], function (list) {
    return list.push(Immutable.fromJS({
        name: 'Some widget2',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }));
});

var newState1 = state.updateIn(['widgets'], function (list) {
    return list.push(Immutable.fromJS({
        name: 'Some widget2',
        type: 'List',
        defaultDataSource: 'daily',
        dataSources: {}
    }));
});

使用 JSON.stringify 怎么样?

JSON.stringify(values) !== JSON.stringify(anothervalue);

如果你知道它们不是圆形对象,并且不包含函数,我认为这是比较它们的最快方法。