3

Is it possible to extend an object without overriding the properties that are already set? In the following example I'm looking for a way to add 2 wings to the cat, but keepings it's 4 legs.

var cat  = { legs: 4 };
var bird = { legs: 2, wings: 2 }

// some references in my application to the original cat
var some_cat = cat;

$.extend( cat, bird );

// expected { legs: 4, wings: 2 }
console.log( some_cat );

Update

I forgot to make it clear in the original question / example, but it is important that it modifies the original cat object.

Dirk Boer
  • 8,522
  • 13
  • 63
  • 111
  • 3
    `$.extend(bird, cat)` ? – Brewal Aug 19 '13 at 07:44
  • 1
    @Brewal Your code is correct but I think Dirk's logic is that `cat` is the original object and thus put as the first argument of `$.extend`... – silkfire Aug 19 '13 at 07:47
  • Indeed @silkfire , sorry my example was not really clear. I've updated the question. – Dirk Boer Aug 19 '13 at 07:55
  • If you want to keep the settings of cat, I think the "logic" would be to have `bird` as "original object" and thus put it as first argument. This is the exact behaviour you are looking for. I don't understand why it wouldn't be a solution. – Brewal Aug 19 '13 at 07:57
  • Because there are already references to `cat` in my application. Switching the parameters wouldn't update the original `cat` object. – Dirk Boer Aug 19 '13 at 07:59
  • `cat = $.extend(bird, cat)` actually "updates" your original `cat` object : [jsFiddle](http://jsfiddle.net/f29fV/2/) – Brewal Aug 19 '13 at 08:02
  • It updates the bird, too. – Paul Aug 19 '13 at 08:06
  • Then just do this : `cat = $.extend({}, bird, cat);` : [jsFiddle](http://jsfiddle.net/f29fV/4/) – Brewal Aug 19 '13 at 08:07
  • @Brewal You're missing the point of OP. He already knows how to solve it, he just wants to know why the order of the arguments are messed up and non-logical. – silkfire Aug 19 '13 at 08:08
  • How about: `var catbird = $.extend({}, bird, cat);` This introduces the new animal without modifying the other 2. – Paul Aug 19 '13 at 08:08
  • I'm afraid your use case falls within this sentence from jQuery docs: `For needs that fall outside of this behavior, write a custom extend method instead.` – Mchl Aug 19 '13 at 08:09
  • `var some_cat = cat; ` makes some_cat and cat point to the same data. Modifying one will modify the other. At first you will think the cats are imitating each other, but it will slowly drive you mad. – Paul Aug 19 '13 at 08:11
  • better read http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object – Paul Aug 19 '13 at 08:12
  • @DirkBoer How can you expect the original `some_cat` to be the same as the modified `cat`? – silkfire Aug 19 '13 at 08:13
  • you need `var cuddles = $.extend({}, cat)` or a cat constructor; see http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object -- it discusses this – Paul Aug 19 '13 at 08:15
  • @Brewal ehh yeah? That's called a reference to the same object? – Dirk Boer Aug 19 '13 at 08:15
  • With `var some_cat = cat;` you just make a new object. – Brewal Aug 19 '13 at 08:17
  • in that line `some_cat` and `cat` are the same object, referred to by different vars – Paul Aug 19 '13 at 08:17

1 Answers1

4

Try something like -

for (prop in bird) {
    if(!cat.hasOwnProperty(prop)) {
        cat[prop] = bird[prop];
    }
}

After cat = {legs: 4, wings: 2}

Gupta.Swap
  • 265
  • 3
  • 14
  • 1
    +1 for no jQuery ;) Also you might want to add `var prop` instead of just `prop` to make the variable local instead of an implied global. – Qantas 94 Heavy Aug 19 '13 at 08:00
  • This seems to work - forgive me for being ignorant, but what is $.extend doing that this simple piece of JS is not doing? Is that only deep copy vs shallow copy? – Dirk Boer Aug 19 '13 at 08:32
  • No, as far as i know $.extend does not follow shallow copying. It just overrides and all the properties from object2 to object1. For more information about $.extend() [read this link](http://api.jquery.com/jQuery.extend/) – Gupta.Swap Aug 19 '13 at 09:37