9

This is a rather general question. Functional-style programming promotes the idea that a program is about transforming data through functions, and that mutation should be avoided (except possibly within a function, seen as a basic unit of abstraction).

But in this program:

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

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

the external variable o is mutated within foo because bar is a reference to o, and, in the end, o === p (they reference the same object). But the functional paradigm would rather expect p to be fresh data.

The obvious solution is to clone the argument (e. g. using underscore/lodash's _.clone):

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

But I wonder if this is the correct way to think about this problem. In a FP perspective, would you consider it a good practice to clone the objects passed as arguments if they will be mutated? (I am aware that not all objects can be cloned easily, if at all, but let's stick to simple cases). Your thoughts?

  • 1
    My 2 cents is to write code that works with the language and not get hung up on programming techniques. Functional programming is fine and dandy, but if you don't need a new object there's no reason to return one, when you can just change the original. – adeneo Mar 01 '15 at 10:13
  • I need to return the object if I want to do something like: `someOtherFunction(foo(o))`. What you probably mean is that it doesn't matter if this is a fresh object or a reference to the external object. – Nicolas Le Thierry d'Ennequin Mar 01 '15 at 10:24
  • Wether it matters or not is up to you? Do you need the original object unchanged, if not there's no reason to create a new one, just return the one passed in to the function after it's modified. – adeneo Mar 01 '15 at 10:25
  • 4
    I think mutating arguments is even despised in non-functional programming, and always needs to be documented/communicated properly – Bergi Mar 01 '15 at 11:40

1 Answers1

9

Ideally the function should return a brand new object everytime it is called. Obviously for performance reasons it is not great, this is why persistent data structures exist. There are a few libraries for JS; immutable-js is arguably the most popular.

Otherwise mutating the object is fine, and in JS it is common practice, since not every project would immediately benefit from persistent data structures, plus the weight of the library.

Also note that in JavaScript everything is passed by value, but values themselves can hold references.

elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • I think it sometimes leads to unexpected results, https://stackoverflow.com/questions/68644126/strange-javascript-variable-re-assignment-issue – Abraham Aug 04 '21 at 01:48