功能风格的JavaScript:避免参数变异的好习惯?

Nic*_*uin 6 javascript functional-programming argument-passing

这是一个相当普遍的问题.功能样式编程促进了程序关于通过函数转换数据的想法,并且应该避免突变(除了可能在函数内,被视为抽象的基本单元).

但在这个计划中:

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

var o = { k1: "apples", k2: "oranges"};
var p = foo(o);
Run Code Online (Sandbox Code Playgroud)

外部变量o在foo中发生变异,因为bar是对o的引用,最后,o === p(它们引用同一个对象).但功能范式宁愿将p视为新数据.

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

function foo (_bar) {
  var bar = _.clone(_bar);
  bar.k1 = "bananas";
  return bar;
}
Run Code Online (Sandbox Code Playgroud)

但我想知道这是否是思考这个问题的正确方法.在FP视角中,如果它们将被突变,你会认为克隆作为参数传递的对象是一个好习惯吗?(我知道并非所有对象都可以轻松克隆,如果有的话,但让我们坚持简单的情况).你的意见?

elc*_*nrs 5

理想情况下,函数应在每次调用时返回一个全新的对象.显然,出于性能原因,这并不是很好,这就是存在持久性数据结构的原因.JS有一些库; immutable-js可以说是最受欢迎的.

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

另请注意,在JavaScript中,所有内容都按值传递,但值本身可以包含引用.