不可变JS比较嵌套结构

Immutable JS compare nested structures

本文关键字:结构 嵌套 比较 JS 不可变      更新时间:2023-09-26

我有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似乎不做深度转换,所以如果你的值是object,它就保持为object。

当你在每个更新步骤中创建不同的对象时,这些对象在相互比较时会被不同地对待,所以你也应该将它转换为Immutable。映射对象,使比较为真。

// 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.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);

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