代码之家  ›  专栏  ›  技术社区  ›  Kevin

不可变.js引用相等

  •  1
  • Kevin  · 技术社区  · 6 年前

    给出以下简单代码:

    const Immutable = require('immutable');
    const a = Immutable.fromJS({
        a: 1,
        b: [2, 3, 4],
        c: {
            d: 1
        }
    });
    const b = a.setIn(['c', 'd'], "Something else");
    const c = b.setIn(['c', 'd'], 1);
    
    console.log(a.equals(b)); // true
    console.log(Immutable.is(a, c)); // true
    console.log(a === c); // false?
    

    在最后的比较中,我希望它会返回真的,因为我正在设置路径 ['c', 'd'] 再回到原来的价值,通过结构共享,我希望它能 c 是否保留对原始数据结构的引用?

    我不明白这是怎么回事吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   SomoKRoceS    6 年前

    首先,这一个 console.log(a.equals(b)); 实际返回假:

    现在回答你的问题,如immutable.js中所述。 here 在“返回自我无操作优化”子章:

    如果可能的话,immutable.js避免为更新创建新对象 如果值没有发生变化,则允许有效引用 相等性检查以快速确定是否没有发生更改。

    举个例子:

    const { Map } = require('immutable');
    const originalMap = Map({ a: 1, b: 2, c: 3 });
    const updatedMap = originalMap.set('b', 2);
    updatedMap === originalMap; // No-op .set() returned the original reference.
    

    但是,会导致更改的更新将返回新的 参考文献。每个操作都是独立进行的,因此有两个 类似的更新不会返回相同的引用:

    这个例子:

    const { Map } = require('immutable');
    const originalMap = Map({ a: 1, b: 2, c: 3 });
    const updatedMap = originalMap.set('b', 1000);
    // New instance, leaving the original immutable.
    updatedMap !== originalMap;
    const anotherUpdatedMap = originalMap.set('b', 1000);
    // Despite both the results of the same operation, each created a new reference.
    anotherUpdatedMap !== updatedMap;
    // However the two are value equal.
    anotherUpdatedMap.equals(updatedMap);
    

    因为你在改变价值, setIn 返回新引用。因此,它们在参考中并不相等。

    希望我能帮忙:)