4

I am trying to update an object that is deeply nested and thus has a rather long name that I do not want to keep typing in my code. In this discussion, I shall call it by the shorter name 'target'.

I begin by referring to it by the shorter name 'c':

c = target

I then want to update its contents using another object; call it update.

If I use c = $.extend(c,update), the reference to c remains 'intact'; i.e. c === target is true.

However, if I use c = {...c, ...update}, a new variable is created; i.e. c === target is false. My original target variable is not updated.

I do not understand why. Can anyone explain?

There is a bin at $extends vs JavaScript spread

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
jladbury
  • 51
  • 5

2 Answers2

3

The jQuery docs are pretty clear about how extend() works:

the target object (first argument) will be modified, and will also be returned from $.extend()

Using the spread operator is different. When you write this:

c = {...c, ...update}

you are creating a new object. You then assign c to point at that new object. The object that c previously pointed to has nothing to do with any of this. It simply (from: tc29/proposal):

copies own enumerable properties from a provided object onto the newly created object

To get the behavior you want you can use Object.assign();

let target = {
  name: "Mark",
  place: "AK"
}

let c = target;

Object.assign(c, {
  name: "Tim"
})
console.log(target)
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 1
    Thanks. Your explanation of the order of things is helpful. I understand it thus: ```{...c,...target}``` creates a new object. The variable name ```c``` is then reassigned to that new object with ```c = {...c,...target}``` – jladbury May 03 '18 at 21:50
  • @jladbury Thanks for your question - I knew about extend but learned about spread. In your case, you don't need (the `c =` part in) `c = $.extend(c, update)`. Because jQuery modifies the first object, `$.extend(c, update)` will give you the same results (and be faster, since you're not writing to `c` twice). Hence, it's common to use `var new = $.extend({}, first, second)` to prevent `$` from modifying `first`. – Travis Bemrose Feb 12 '23 at 00:36
1

The description of $.extend() reads as follows:

Merge the contents of two or more objects together into the first object.

Meaning, merge two objects and modify the first object with the properties of the seconds (or third, fourth, etc.)

JavaScript is pass-by-reference, so, when updating c (not when setting it to a new value) you are modifying the same object that target is a reference to.

c = {...c, ...update};

is setting c to the combination of c and update, while

$.extend(c,update);

is modifying the object that c is a reference to by adding the properties of update.

I hope that makes it clear

Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44