我如何使用facebook/immutable-js自定义不可变类型
How do I make a custom immutable type using facebook/immutable-js?
我试图使一个简单的不可变的间隔类型。它有起始和结束属性。有没有一种直接的方法来利用immutable-js库来创建自己的自定义不可变类型?
我当前尝试使用包含不可变的模式。映射和不可变。列表不太好用。例如,difference
应该返回一个不可变的Interval列表,但是因为它创建了Interval的新实例,所以它返回的list不会传递相等值。
感觉我采取了错误的方法,但我不确定是怎么回事。我可以很容易地用Immutable.Map
表示数据,但是我想把difference
包含在它的公共接口中,而不包括一般的Map
方法,如get和set。也就是说,我希望它是不可变的,但它是自己的类型,有自己的接口。
var Immutable = require('immutable')
function Interval(start, end) {
this.value = Immutable.Map({
start: start,
end: end
})
}
Interval.prototype.start = function () {
return this.value.get('start')
}
Interval.prototype.end = function () {
return this.value.get('end')
}
Interval.prototype.equals = function(interval) {
return this.value.equals(interval.value)
}
Interval.prototype.difference = function (subtrahend) {
var nonoverlapping = subtrahend.start() > this.end() || subtrahend.end() < this.start()
return nonoverlapping ? Immutable.List.of(this) :
Immutable.List.of(
new Interval(this.start(), subtrahend.start()),
new Interval(subtrahend.end(), this.end())
)
.filter(function(interval) {
return interval.end() > interval.start()
})
}
一些测试:it('should return an empty array for an exact difference', function() {
var interval = new Interval(80, 90)
interval.difference(interval)
.equals(Immutable.List())
.should.be.true
})
it('should return an array with the same Interval for a missed difference', function() {
var interval = new Interval(80, 90)
console.log(interval.difference(new Interval(50, 60)).toJS());
interval.difference(new Interval(50, 60))
.equals(Immutable.List.of([
{ value: Immutable.Map({ start: 80, end: 90 }) }
]))
.should.be.true
})
为什么不使用Record
type:
var Interval = Immutable.Record({start: 0, end: 1})
为您创建记录类型,分别用默认值0和1定义start
和end
属性。
现在要创建Interval
的实例,只需执行:
var newInterval = new Interval() //will have default values above
var newInterval = new Interval({start: 10, end: 30)
注意Record
类型的实例只是值类型,所以它们应该只包含数据。当然,您可以定义对该数据值进行操作的函数。
var difference = function (interval1, interval2) {
var nonoverlapping = interval2.start > interval1.end || interval2.end < interval1.start
return nonoverlapping ? Immutable.List.of(interval1) :
Immutable.List([
new Interval({start: interval1.start, end: interval2.start}),
new Interval({start: interval2.end, end: interval1.end})
])
.filter(function(interval) {
return interval.end > interval.start
});
}
使用Immutable.is(interval1, interval2)
,您可以免费获得相等性有关记录的更多信息,请键入:http://facebook.github.io/immutable-js/docs/#/Record
你可以使用" extenable -immutable"库
那就简单了:
const {Map} = require('extendable-immutable');
class Interval extends Map {
constructor(start, end) {
super({
value: new Map({start: start, end: end})
});
}
start() {
return this.get('value').get('start');
}
end() {
return this.get('value').get('end');
}
//...
}
如果您像我一样选择方法(如start, end)而不是字段,我不建议您记录。如果您使用Record实现它,您将拥有自动公开的字段。
您可能想要使用_value
字段创建您的Record自定义类,而不是暴露value
字段,然而这并不总是可能的。看到:
实现valueOf
方法
Interval.prototype.valueOf = function() {
return Map({ class: Interval, value: this.value });
}
和测试:
Immutable.is(new Interval(80, 90), new Interval(80, 90)); // true
另一个选择是通过实现方法equals
和hashCode
将类转换为ValueObject(使用函数Immutable.is
和Immutable.hash
来实现)。
- Dojo不解析自定义小部件的模板html中的小部件声明性
- Meteor-添加用户自定义字段的方法不起作用
- 自定义运行时Can'在谷歌应用引擎中看不到我的自定义日志
- 自定义验证器不工作
- 自定义控件中的双向绑定在SAPUI5中不起作用
- Asp自定义验证器在IE-11中不起作用
- 使用自定义css在页面中弹出,而不覆盖页面's css
- 嵌入的自定义谷歌地图不会在没有刷新的情况下显示
- 加载自定义类在ExtJs中不起作用
- Select2-使用自定义模板时不显示占位符
- 自定义HTML5视频控件-退出按钮不会启动全屏切换功能
- 如何在推特中使用自定义的bit.ly URL,而不是t.co
- 类别自动完成jQuery中的单词级自定义筛选器,而不是子字符串
- 不使用自定义CSS或HTML(使用框架方法)的角度材质文本输入或文本区域标签大小
- Wordpress在播放器旁边播放一个自定义的下载按钮,而不是下载
- 如何为wordpress创建一个自定义(不使用插件)新闻阅读器
- 我如何使用facebook/immutable-js自定义不可变类型
- 在自调用函数中不可变的未定义
- 自定义不区分大小写排序函数,保留原始的大小写
- AddThis代码的自定义不起作用