这是一个相当普遍的问题。函数式编程促进了程序关于通过函数转换数据的想法,并且应该避免突变(除了可能在函数内部,被视为抽象的基本单元)。
但在这个计划中:
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视角中,如果它们将被突变,你会认为克隆作为参数传递的对象是一个好习惯吗? (我知道并非所有对象都可以轻松克隆,如果有的话,但让我们坚持简单的情况)。你的想法?
答案 0 :(得分:5)
理想情况下,函数应在每次调用时返回一个全新的对象。显然,出于性能原因,它并不好,这就是persistent data structures存在的原因。 JS有一些库; immutable-js可以说是最受欢迎的。
否则改变对象很好,在JS中这是常见的做法,因为不是每个项目都会立即受益于持久数据结构,加上库的权重。
另请注意,在JavaScript中,所有内容都是按值传递的,但值本身可以保存引用。