Javascript 使用带有重参数的纯函数会有性能损失吗?

Javascript 使用带有重参数的纯函数会有性能损失吗?,javascript,typescript,performance,functional-programming,arguments,Javascript,Typescript,Performance,Functional Programming,Arguments,我真的很喜欢纯函数方法有很多原因,但是我最喜欢的是它是否有相当大的性能损失,特别是在有严重争论的情况下 例如,与此相反: //没有纯函数 从“./某处”导入bigState//想象一个具有许多值的整个状态。 常量不纯=()=>{ //对bigState做点什么 } //纯函数 常量纯=(bigState)=>{ //对bigState做点什么 } 如果一个应用程序在处理此类函数和参数时做了大量工作,它会受到惩罚吗?如果你想使用纯函数,你必须传入一个只读对象,而这个对象是你不能修改的。要修改状态

我真的很喜欢纯函数方法有很多原因,但是我最喜欢的是它是否有相当大的性能损失,特别是在有严重争论的情况下

例如,与此相反:

//没有纯函数
从“./某处”导入bigState//想象一个具有许多值的整个状态。
常量不纯=()=>{
//对bigState做点什么
}
//纯函数
常量纯=(bigState)=>{
//对bigState做点什么
}

如果一个应用程序在处理此类函数和参数时做了大量工作,它会受到惩罚吗?

如果你想使用纯函数,你必须传入一个只读对象,而这个对象是你不能修改的。要修改状态,纯函数必须返回状态的一个副本,并进行修改,而不是更新原始状态

就传递参数而言,状态的大小实际上并不相关。您传入一个(小)对大状态对象的引用,而不是实际对象本身。无论状态有多大,参数的大小都是相同的

如果您的状态非常大,那么每次进行修改时,使用严格纯函数将导致大量复制状态

为了解决这个问题,您可以考虑使用状态管理工具(如immutable.js或redux)为您提供性能优化

更新

我应该补充一点,关于纯函数,重要的不是它如何从调用环境获取输入,而是它如何处理输入。如果一个函数有副作用,那么它就不是纯函数,不管它是使用参考参数还是全局变量来引起副作用

在函数式语言(如Haskell)中,编译器将帮助您避免创建不纯净的函数。javascript等语言没有直接的函数式编程支持,您必须通过自己编写函数式代码来确保可重复性并避免副作用

帮助在javascript/typescript中实现这一点的最简单方法之一是使用不可变状态*。如果您的状态是不可变的,那么在函数执行期间,您很难意外地更改它。它还将有助于在传递引用变量时确保可重复的结果。如果被引用的对象是不可变的,那么如果对同一对象的引用再次传递到函数中,则可以依赖函数来提供一致的结果


*当然,javascript中很少有是只读的。如果开发人员足够努力,他们总会有办法颠覆您的只读意图。

我想补充一点,因为不可变性使事情变得如此可预测,不可变的数据结构可以共享

最简单的示例是单链表:

const c = {head: "c", tail: null};
const bc = {head: "b", tail: c};
const abc = {head: "a", tail: bc};

// zbc and abc share bc
const zbc = {head: "z", tail: bc};

const join = ({head, tail}) =>
  tail == null
  ? head
  : head + join(tail)
;

join(abc) // "abc"
join(zbc) // "zbc"

如果按照建议使用不可变的数据结构,它们将与结构共享一起提供


当你来自命令式世界时,对不变性的一种自然解释是,你必须先对事物进行深度复制,然后才能安全地将它们与突变联系起来,但反过来说:因为没有突变,所以你不需要进行深度复制。

如果你将一个对象传递给一个函数,那就是通过引用,所以严格地说,一旦对象被修改,它就不再是纯粹的了。这有什么关系呢?您认为大型对象引用会更慢吗?你不会像拿着一个装满东西的大箱子那样把东西到处传递。你在传递一个推荐人。这就像当你想在一家大商店里买一件大东西,你拿着一张纸走到前面。你没有在商店里拖拽那件大东西。一个对象不像一个字符串。如果是,它将是不变的。你所说的“激烈争论”到底是什么意思?很多吗?或者只是对一个具有许多属性的巨大对象的引用?嗨,我猜你的意思是不可变的。js@geoffrey-谢谢,是的,我是说immutable.js。免疫是我们图书馆的私人绰号,我搞混了。