我试图将函数传递给Map
,就像使用对象文字表示法一样。有没有任何本机可以调用函数,就像你在枚举上使用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
答案 0 :(得分: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.js并使用:
Object.freeze (person);
这使得对象本身不可变,没有集合固有的危险。如果由于某种原因只是必须有一个集合,则必须扩展集合类和/或使用代理来获取format
以从其包含集合中获取其他条目,以便person
可以独立变异。请注释是否是这种情况,我可以告诉你如何做,但我不熟悉Immutable.js类,代理是一个复杂的野兽。