【问题标题】:Immutable.js getters for invoking functions in object literal notationImmutable.js getter 用于以对象文字表示法调用函数
【发布时间】:2017-07-03 09:46:08
【问题描述】:

我正在尝试将函数传递给Map,就像使用对象文字表示法一样。 Immutable 是否有任何本机方法可以调用该函数,就好像您在可枚举对象上使用 getter 方法一样?

var person = {
  firstName: 'John',
  lastName: 'Smith',
  format: function() {
    return this.lastName + ', ' + this.firstName;
  }
};

person.format(); // 'Smith, John'

var personMap = new Immutable.Map(person);

personMap.get('format'); // function() {return ... // doesn't work

【问题讨论】:

  • 你能量化“更清洁”吗?我认为format 也不会在这里拥有正确的this
  • 为了清楚起见,我进行了编辑。
  • 我只想说 immutable.js 不能这样工作。代码中的this 肯定指向其他地方。
  • 感谢您的澄清。

标签: javascript immutable.js enumerable


【解决方案1】:

我不熟悉 Immutable.js,但您始终可以在函数进入集合之前将其绑定到正确的 this

最简单的情况:

person.format.bind (person);
// create immutable here

更一般地说,如果我可以假设集合是您打算引用对象的唯一方式,并且继承的方法不是问题:

function objectAsCollection (object) {
    var key;
    for (key of Object.keys (object)) {
        if (typeof object [key] == "function") {
            object [key] = object [key].bind (object);
       }
    }
    return new Immutable.Map (object);
}

这确实修改了原始对象,但调用person.format () 不受影响,mapYouMade.get ("format")() 将有this 指向person。根据您的代码的其余部分,可能会出现一些问题:

  • 如果person 成为对象或类的原型,则函数的行为将始终如同this.format 仍然引用原型而不是派生对象一样。
  • 如果修改了person.whateverProperty,则更改不会反映在不可变映射中,但theMap.get ("format")()将使用新值,因为它绑定到原始对象,而不是映射中的条目,这意味着immutable 将是相当可变的。

听起来你想要的实际上不是一个不可变的映射,而是一个不可变的对象;毕竟,集合是用于同质值类型的,而方法属于它们所属的对象。在这种情况下,我的建议是忘记 Immutable.js 并使用:

Object.freeze (person);

这使得对象本身不可变,没有集合固有的危险。如果出于某种原因您只是必须拥有一个集合,则必须扩展集合类和/或使用代理来获取 format 以从其包含的集合中获取其他条目,以便 person 可以独立地变异。如果是这种情况请发表评论,我可以告诉你怎么做,但我不熟悉 Immutable.js 类,代理是一个复杂的野兽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-28
    • 2011-10-02
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多