Immutable.js 的实际情况是什么?
What is the practical case of the Immutable.js?
我了解 JS 中不变性的好处。但是无法获得为此使用特定库的任何优势。
图书馆主页上有一个很好的“不变性案例”段落,但没有明确回答“Immutable.js案例”。
我的意思是要在 JS 应用程序中实现不变性,您应该只保留像 Object.prototype.assign
、Array.prototype.concat
这样的简单模式,即不要直接改变数据,而是返回一个新副本而不触及源.
为什么我更喜欢 Immutable.List
而不是原生数组,Immutable.Map
而不是 ES6 Map
等等?
这是自我约束的问题吗?如果是这样,我是否应该忘记我的应用程序中的本机数据结构并仅使用 Immutable.js 替代方案?
这是为了提高生产力(在速度和硬件资源方面)的一种开销吗?
它是避免错误和降低应用状态复杂性的高级工具吗?
I mean to achieve immutability in JS app you should just to keep simple patterns like Object.prototype.assign
, Array.prototype.concat
, i.e. don’t mutate data directly, but returning a new copy not touching the source.
要是这么简单就好了。
包含串联数组的数组
var a = [ [1] ];
var b = [ [2] ];
var c = a.concat(b);
c[0].push(42);
console.log("Array c contains", c);
console.log("Array a contains", a);
包含被串联对象的数组
var a = [ { name: "Alice" } ];
var b = [ { name: "Bob" } ];
var c = a.concat(b);
c[0].age = 42;
console.log("Array c is", c);
console.log("Array a is", a);
包含数组的对象和其他组合在一起的对象
var a = {
name: "Alice"
}
var foods = {
favouriteFoods: [
"noodles",
"pancakes"
]
};
var seasons = {
thoughtsOnSeasons: {
spring: "Beautiful",
summer: "Too hot",
autumn: "Pretty",
winter: "Festive"
}
};
//this object is now entirely new
var alice = Object.assign({}, a, foods, seasons);
//let's manipulate one of the old objects
foods.favouriteFoods.length = 0;
foods.favouriteFoods.push("carrots");
//let's manipulate one of the properties of the new object
alice.thoughtsOnSeasons.spring = "boring";
alice.thoughtsOnSeasons.summer = "boring";
alice.thoughtsOnSeasons.autumn = "boring";
alice.thoughtsOnSeasons.winter = "boring";
//manipulated through the composed object
console.log(seasons);
//manipulated through the previous object
console.log(alice);
所以,这实际上是一个非常简单的示例,应该告诉您您最初的假设是错误的 - 它 不是 一个简单的模式。如果你的想法是"OK, I will just have to write my own functions that perform a deep clone of arrays and objects",那我们再看一件事
var bobby = { name: "Bobby Tables" };
var map = new Map();
map.set("student", bobby);
bobby.name = "Robert'); DROP TABLE Students; --";
console.log(map.get("student"));
如果您还在考虑 "It's fine, I'll have my own Map clone utility",那么您刚刚意识到您需要一些可以为您克隆属性的东西。
如果你当时的想法是 "I'll use a library that does that" 那么你已经提出了 Immutable.js 的观点。
但这还没有触及不变性,这是 Immutable.js 提供的主要内容,而不仅仅是一个花哨的克隆实用程序。事实上,您通常不希望或不期望使用代码来操纵您的 return。您可以 returning 包含数组的数组或包含对象的对象,这很好,但如您所见,对 them 的任何更改都可能导致引用数据发生更改。否则,结果的更改也可能是不受欢迎的,而且发生这种情况就像拼写错误一样简单。如果您明确不希望结果被操纵,那么您可以 return 它的不可变视图。在许多方面,这类似于您确保在接收数据时进行深度克隆,但它只是强制执行该行为,让您知道是否没有。
所以,让我试着倒序回答你的问题
Is it an advanced tool to avoid errors and reducing the complexity of app state?
是的,您可以使用它来避免问题和复杂性。这是共享可变数据面临的主要问题,真的 - 错误源于意外修改数据和必须考虑它的复杂性。
Is this a kind of overhead to achieve more productivity (in terms of speed and hardware resources)?
就速度和硬件资源而言 - 几乎没有。可能有 一些 ,但我实际上没有任何关于 Immutable.js 性能的数据,但是,我知道不可变数据结构在某些情况下可以提高内存效率方式,由于结构共享。可以附加一个不可变列表,你会得到一个 "new" 列表,但是,在内部,列表的开头在实例之间共享,因此你可以避免一些 GC 开销。另一方面,对于不可变数据结构,某些其他操作可能需要更多 CPU 时间,例如,更改特定索引上的数据。不过,总的来说,我不会太担心性能。
您获得最大收益的是开发人员时间和可维护性。
Is this a question of self-constrains? If so, should I forget about native data structures in my app and use only Immutable.js alternative?
应该吗?这是一个完全不同的问题。您不必,甚至可能不需要。这取决于您正在从事的项目以及方式。在一个小项目中与 Immutable.js 一起工作并获得很多好处是完全可能的。完全有可能在没有 Immutable.js 的情况下从事大型项目并且不会因此而受苦。在某些方面,这是个人选择。我会说使用不变性绝对有用,因此您可以获得第一手经验。您是否需要在任何地方都使用它,并不能轻易回答,但您将获得自己评估的方法。
我了解 JS 中不变性的好处。但是无法获得为此使用特定库的任何优势。
图书馆主页上有一个很好的“不变性案例”段落,但没有明确回答“Immutable.js案例”。
我的意思是要在 JS 应用程序中实现不变性,您应该只保留像 Object.prototype.assign
、Array.prototype.concat
这样的简单模式,即不要直接改变数据,而是返回一个新副本而不触及源.
为什么我更喜欢 Immutable.List
而不是原生数组,Immutable.Map
而不是 ES6 Map
等等?
这是自我约束的问题吗?如果是这样,我是否应该忘记我的应用程序中的本机数据结构并仅使用 Immutable.js 替代方案?
这是为了提高生产力(在速度和硬件资源方面)的一种开销吗?
它是避免错误和降低应用状态复杂性的高级工具吗?
I mean to achieve immutability in JS app you should just to keep simple patterns like
Object.prototype.assign
,Array.prototype.concat
, i.e. don’t mutate data directly, but returning a new copy not touching the source.
要是这么简单就好了。
包含串联数组的数组
var a = [ [1] ];
var b = [ [2] ];
var c = a.concat(b);
c[0].push(42);
console.log("Array c contains", c);
console.log("Array a contains", a);
包含被串联对象的数组
var a = [ { name: "Alice" } ];
var b = [ { name: "Bob" } ];
var c = a.concat(b);
c[0].age = 42;
console.log("Array c is", c);
console.log("Array a is", a);
包含数组的对象和其他组合在一起的对象
var a = {
name: "Alice"
}
var foods = {
favouriteFoods: [
"noodles",
"pancakes"
]
};
var seasons = {
thoughtsOnSeasons: {
spring: "Beautiful",
summer: "Too hot",
autumn: "Pretty",
winter: "Festive"
}
};
//this object is now entirely new
var alice = Object.assign({}, a, foods, seasons);
//let's manipulate one of the old objects
foods.favouriteFoods.length = 0;
foods.favouriteFoods.push("carrots");
//let's manipulate one of the properties of the new object
alice.thoughtsOnSeasons.spring = "boring";
alice.thoughtsOnSeasons.summer = "boring";
alice.thoughtsOnSeasons.autumn = "boring";
alice.thoughtsOnSeasons.winter = "boring";
//manipulated through the composed object
console.log(seasons);
//manipulated through the previous object
console.log(alice);
所以,这实际上是一个非常简单的示例,应该告诉您您最初的假设是错误的 - 它 不是 一个简单的模式。如果你的想法是"OK, I will just have to write my own functions that perform a deep clone of arrays and objects",那我们再看一件事
var bobby = { name: "Bobby Tables" };
var map = new Map();
map.set("student", bobby);
bobby.name = "Robert'); DROP TABLE Students; --";
console.log(map.get("student"));
如果您还在考虑 "It's fine, I'll have my own Map clone utility",那么您刚刚意识到您需要一些可以为您克隆属性的东西。
如果你当时的想法是 "I'll use a library that does that" 那么你已经提出了 Immutable.js 的观点。
但这还没有触及不变性,这是 Immutable.js 提供的主要内容,而不仅仅是一个花哨的克隆实用程序。事实上,您通常不希望或不期望使用代码来操纵您的 return。您可以 returning 包含数组的数组或包含对象的对象,这很好,但如您所见,对 them 的任何更改都可能导致引用数据发生更改。否则,结果的更改也可能是不受欢迎的,而且发生这种情况就像拼写错误一样简单。如果您明确不希望结果被操纵,那么您可以 return 它的不可变视图。在许多方面,这类似于您确保在接收数据时进行深度克隆,但它只是强制执行该行为,让您知道是否没有。
所以,让我试着倒序回答你的问题
Is it an advanced tool to avoid errors and reducing the complexity of app state?
是的,您可以使用它来避免问题和复杂性。这是共享可变数据面临的主要问题,真的 - 错误源于意外修改数据和必须考虑它的复杂性。
Is this a kind of overhead to achieve more productivity (in terms of speed and hardware resources)?
就速度和硬件资源而言 - 几乎没有。可能有 一些 ,但我实际上没有任何关于 Immutable.js 性能的数据,但是,我知道不可变数据结构在某些情况下可以提高内存效率方式,由于结构共享。可以附加一个不可变列表,你会得到一个 "new" 列表,但是,在内部,列表的开头在实例之间共享,因此你可以避免一些 GC 开销。另一方面,对于不可变数据结构,某些其他操作可能需要更多 CPU 时间,例如,更改特定索引上的数据。不过,总的来说,我不会太担心性能。
您获得最大收益的是开发人员时间和可维护性。
Is this a question of self-constrains? If so, should I forget about native data structures in my app and use only Immutable.js alternative?
应该吗?这是一个完全不同的问题。您不必,甚至可能不需要。这取决于您正在从事的项目以及方式。在一个小项目中与 Immutable.js 一起工作并获得很多好处是完全可能的。完全有可能在没有 Immutable.js 的情况下从事大型项目并且不会因此而受苦。在某些方面,这是个人选择。我会说使用不变性绝对有用,因此您可以获得第一手经验。您是否需要在任何地方都使用它,并不能轻易回答,但您将获得自己评估的方法。