【问题标题】:Functional-style JavaScript: good practice to avoid argument mutation?函数式 JavaScript:避免参数突变的好习惯?
【发布时间】:2015-05-01 18:34:30
【问题描述】:

这是一个相当笼统的问题。函数式编程提倡程序是通过函数转换数据的想法,并且应该避免突变(可能在函数内部除外,被视为基本抽象单元)。

但是在这个程序中:

function foo (bar) {
  bar.k1 = "bananas";
  return bar;
}

var o = { k1: "apples", k2: "oranges"};
var p = foo(o);

外部变量 o 在 foo 中发生了变异,因为 bar 是对 o 的引用,最后是 o === p(它们引用同一个对象)。但函数范式更希望 p 是新数据。

显而易见的解决方案是克隆参数(例如,使用下划线/lodash 的_.clone):

function foo (_bar) {
  var bar = _.clone(_bar);
  bar.k1 = "bananas";
  return bar;
}

但我想知道这是否是思考这个问题的正确方法。从 FP 的角度来看,如果它们会发生变异,您是否认为克隆作为参数传递的对象是一种好习惯? (我知道并非所有对象都可以轻松克隆,但让我们坚持简单的情况)。你的想法?

【问题讨论】:

  • 我的 2 美分是编写适用于该语言的代码,而不是沉迷于编程技术。函数式编程很好也很花哨,但是如果您不需要新对象,则没有理由返回一个对象,您只需更改原始对象即可。
  • 如果我想做类似的事情,我需要返回对象:someOtherFunction(foo(o))。您可能的意思是,这是一个新对象还是对外部对象的引用都没有关系。
  • 重要与否取决于你?是否需要原对象不变,如果没有就没有理由创建一个新对象,只需将传入的对象修改后返回给函数即可。
  • 我认为变异参数在非函数式编程中甚至被鄙视,并且总是需要正确记录/沟通

标签: javascript functional-programming argument-passing


【解决方案1】:

理想情况下,该函数在每次调用时都应返回一个全新的对象。显然出于性能原因它不是很好,这就是persistent data structures 存在的原因。有一些 JS 库; immutable-js 可以说是最受欢迎的。

否则改变对象是好的,在 JS 中这是常见的做法,因为不是每个项目都会立即受益于持久数据结构,加上库的重量。

还要注意,在 JavaScript 中,一切都是按值传递的,但值本身可以保存引用。

【讨论】:

猜你喜欢
  • 2020-03-01
  • 1970-01-01
  • 2011-07-13
  • 2019-06-16
  • 1970-01-01
  • 2021-03-15
  • 2017-09-11
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多