[翻译]ImmutableJS Records的简介以及一些用法实例
作者:Ahmad Bamieh
出处:https://medium.com/@bamieh/immutablejs-records-bd369137da06
Immutable Records are immutably beautiful! — Ahmad Bamieh
Immutable 的 Record 使用起来非常简单,但与比我们经常使用 Immuable 的 Map 相比,它提供的优势更大。
Record的特性
Record跟Immuable的Map很像,但是它有以下独特的特点,使它具有特殊性:
- 一旦构造好,就不能添加更多的属性(key)。
- 可以给Recor的实例定义默认值。
- Record实例的属性可以像普通JS对象那样访问,也可以将它删除。
- 可以对Record进行命名,以便更好地进行debug和错误处理。
- 可以对Record进行扩展(extend),以从Record中提供派生数据。
这篇文章将讨论以上的所有属性,我们先从创建我们的第一个Record开始吧!
创建Record
Record方法返回一个构造函数,在该函数中可以生成新的实例。
const LivingCreature = new Immutable.Record({
name: "Unknown",
age: 0,
species: "Human",
});
let fooBar = new LivingCreature({name: "Foo Bar", age: 24});
在这段代码中,我们通过Record创建了一个 LivingCreature ,并创建了一个 LivingCreature的实例FooBar。值得注意的是,此实例具有默认的Humans属性。
添加描述
可以给Record传入第二个参数,用于描述它的特征,该参数将在Record被转换为字符串或任何错误消息时出现。
const NamedRecord = new Immutable.Record({...}, "[[NAME HERE]]");
直接访问Record的属性
与其他Immuable的JS对象不同的是,Record实例的属性可以像普通的JS对象那样访问( records can be accessed like normal JS objects)。
const {name, species} = fooBar
fooBar.name // Foo Bar
fooBar["species"] // Human
替换其值
要用另一个LivingCreature替换fooBar,只需重新赋值。
fooBar = new LivingCreature({name: "Foo Bar Junior", age: 8, species: "Half Blood"});
更新其值
除了使用set更新单个值之外,还可以使用merge一次更新多个值。
fooBar.set("age", 20);
// or
fooBar.merge({
age: 25,
species: 12,
})
// Record {name: "Foo Bar Junior", age: 25, species: 12}
添加新属性
如果你尝试添加未初始化的属性,则该record将引发错误。以下示例将引发错误:
const newFooBar = new LivingCreature({status: "its complicated"});
const mergeFooBar = fooBar.merge({status: "its complicated"});
译者注:在实验过程中,并没有出现上述的报错情况,只是不能merge成功
删除属性
从record中删除属性只会将其重置为该属性的默认值。
const newFooBar2 = fooBar.remove('name');
console.log(newFooBar2.name) // → "Unknown"
派生值
我个人最喜欢records的一个功能是他们从记录本身中获取数据的能力。
例如,假设我们有一个包含itemA、temB已经sum的“购物车”。在通常情况下,每次更新itemA、itemB值时,我们也必须更新sum。但这不是最好的做法。
看records是如何的:
class Cart extends Immutable.Record({ itemA: 1, itemB: 2 }) {
get sum() {
return this.itemA + this.itemB;
}
}
var myCart = new Cart()
myCart.sum // 3
现在我们可以更新任何值,因为sum来自record的属性,所以无需担心或手动更新。
总结
Records有一个优点是,允许你的Immuable对象可以像普通对象一样被处理,具有标准访问器和对象解构,因此任何不可遍对象(mutate objects)的库或组件都会欢迎像他们自己的records!
此外,由于在创建record时必须指定它的属性(keys),因此阅读record将阐明其用途和 self-document 的用途。它还强制执行更严格的代码样式,因为您不能再向record中添加属性。
在使用record之后,我奇怪它为什么很少谈及,为什么它不是比Map Immutable更标准。