1

According to the lodash docs, _.extend(object, [sources]) mutates the first parameter.

var dest = {
  a: 1
};
_.extend(dest, {
  b: 2
});

// expect { "a": 1, "b": 2 }
// actual { "a": 1, "b": 2 }
console.log(dest);
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.js"></script>

When using lodash/fp, this is not the case (argument order is unchanged):

var dest = {
  a: 1
};
_.extend(dest, {
  b: 2
});

// expect { "a": 1, "b": 2 }
// actual { "a": 1 }
console.log(dest);
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.fp.js"></script>

This is problematic as I have a lot of code that mutates this. Is this a bug in lodash and is there a workaround?

Community
  • 1
  • 1
Musical Shore
  • 1,361
  • 3
  • 20
  • 41

2 Answers2

2

It's not a bug: immutability is a functional programming trait and it's stated at the very beginning of the guide:

The lodash/fp module promotes a more functional programming (FP) friendly style by exporting an instance of lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.

I think you should reconsider using lodash/fp or mutations, they don't play well together.


Edit: well I was mistaken, they can play together: see Musical Store's answer

Community
  • 1
  • 1
martriay
  • 5,632
  • 3
  • 29
  • 39
2

The solution is to configure lodash/fp to allow mutations.

var fp = _.convert({
  'immutable': false
})
var dest = {
  a: 1
};
fp.extend(dest, {
  b: 2
});

// expect { "a": 1, "b": 2 }
// actual { "a": 1, "b": 2 }
console.log(dest);
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.fp.js"></script>

I am using KnockoutJS with viewModels defined as functions, which necessitates mutating this. If I don't want to disable immutability with lodash/fp, I can define my viewModels as object literals instead. More here.

Community
  • 1
  • 1
Musical Shore
  • 1,361
  • 3
  • 20
  • 41