Immutable.js的实际情况是什么?
What is the practical case of the Immutable.js?
我理解JS中不变性的好处。但是不能得到使用特定库的任何好处。
在图书馆的主页上有一个很好的"不变性的案例"段落,但是对于"不可变的案例"没有明确的答案。
我的意思是在JS应用程序中实现不变性,你应该只保持简单的模式,如Object.prototype.assign
, Array.prototype.concat
,即不直接改变数据,但返回一个新的副本不触及源。
为什么我应该更喜欢Immutable.List
而不是本机阵列,Immutable.Map
而不是ES6 Map
等等?
这是一个自我约束的问题吗?如果是这样,我应该忘记本地数据结构在我的应用程序,只使用Immutable.js替代吗?
这是实现更高生产力的一种开销(在速度和硬件资源方面)吗?
是一个先进的工具,以避免错误和减少应用程序状态的复杂性?
我的意思是在JS应用程序中实现不变性,你应该只保持简单的模式,如
Object.prototype.assign
,Array.prototype.concat
,即不直接改变数据,而是返回一个新的副本,不触及源。
要是有那么简单就好了。
包含正在连接的数组的数组
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);
所以,这实际上是一个非常简单的例子,它应该告诉你你最初的假设是错误的——它是而不是一个简单的模式。如果你的想法是"好吧,我只需要编写自己的函数来执行数组和对象的深度克隆",那么让我们再看一件事
var bobby = { name: "Bobby Tables" };
var map = new Map();
map.set("student", bobby);
bobby.name = "Robert'); DROP TABLE Students; --";
console.log(map.get("student"));
如果你还在想"这很好,我会有我自己的地图克隆实用程序",那么你刚刚意识到你需要的东西克隆属性为你。
如果你的想法是"我将使用一个库来实现这一点",那么你已经为Immutable.js提出了一个观点。
但这还没有涉及到不可变性,这是Immutable.js提供的主要功能,而不仅仅是一个花哨的克隆工具。事实是,您通常不希望或不期望消费代码操纵您的返回。您可以返回包含数组的数组或包含对象的对象,这很好,但是正如您所看到的,对它们的任何更改都可能导致对引用数据的更改。否则,对结果的更改也可能是不希望发生的,这就像发生错别字一样简单。如果显式地不希望对结果进行操作,则可以返回它的不可变视图。在许多方面,这类似于你在接收数据时确保进行深度克隆,但它只是强制执行该行为,使你意识到如果你没有。
那么,让我试着倒序回答你的问题
是一个先进的工具,以避免错误和减少应用程序状态的复杂性?
是的,你可以用它来避免问题和复杂性。这是你面对共享可变数据的主要问题,真的——错误源于意外修改数据和必须对其进行解释的复杂性。
这是实现更高生产力的一种开销(在速度和硬件资源方面)吗?
在速度和硬件资源方面-几乎没有。可能有一些,但我实际上没有关于immutable .js性能的任何数据,然而,我确实知道,由于结构共享,不可变数据结构在某些方面可以提高内存效率。一个不可变的列表可以被追加到,然后你得到一个"新"列表,但是,在内部,列表的开头是在实例之间共享的,所以你避免了一些GC开销。另一方面,对于不可变数据结构,其他一些操作可能会占用更多的CPU时间,例如,更改特定索引上的数据。但是,总的来说,我不会太担心性能。
您从中获得的最大好处是开发人员的时间和可维护性。
这是一个自我约束的问题吗?如果是这样,我应该忘记本地数据结构在我的应用程序,只使用Immutable.js替代吗?
应该吗?这是一个完全不同的问题。你不需要,甚至不需要。这取决于你在做什么项目以及如何做。在一个小项目中使用Immutable.js并获得很多好处是完全可能的。在没有Immutable.js的大型项目中工作而不受其影响是完全可能的。在某种程度上,这是个人的选择。我想说,使用不变性绝对是有用的,这样你就可以获得第一手的经验。你是否需要在任何地方使用它,真的不容易回答,但你将获得自己评估的方法。
- 在这种情况下,*[Symbol.iterator]的含义是什么
- 在这种情况下,“foo[x]”是什么意思?
- Array.prototype.reduce的实际用途是什么
- Java开发人员在不编写Javascript的情况下生成Javascript的最佳方式是什么
- 跨领域意味着什么?JSONP在这种情况下的立场是什么
- 以下情况的有效正则表达式是什么
- 在没有服务器根访问权限的情况下构建聊天脚本的有效方法是什么
- 在不影响布局的情况下降低鼠标悬停元素周围的灵敏度的简单方法是什么
- 在浏览器返回时使window.history.state null的可能情况是什么
- 在这种情况下,正则表达式中的“[”是什么( 2 个问题)
- 在MySQL,PHP或一般情况下排序时字符的优先级是什么
- 使用 nodejs & expressjs:在不模板的情况下将 .env 传递给 html 的好方法是什么?
- 在没有协议的情况下编写的 URL 的规则是什么
- 在默认情况下将可枚举设置为 false 的 JS 中创建对象属性的其他方法是什么
- Koa:在没有现有包装器的情况下连接到数据库的最明智的方法是什么?
- 在每秒 10 次调用限制的情况下一次发出 50 个 API 请求的有效方法是什么(烂番茄 API)
- ES5提供的新方法的实际用途是什么?
- 在不重新加载的情况下在页面内跳转要收听的事件是什么
- 在不超过堆栈限制的情况下,迭代或递归大量庞大函数的最佳方式是什么
- Immutable.js的实际情况是什么?