clentfort
clentfort

Reputation: 2504

jQuery extend with prototypes

Hi I am relatively new to jQuery and JavaScript and have a question regarding the functionality of $.extend. I am using extend to overwrite the prototype of a class that extends a "base class". Lets call the base Parent and the the children/extend classes A and B. Now when I use $.extend(true, A.prototype, {someObject: {extraKey: 'value'}}); it seems also the Prototype of Parent is changed regarding the contents of someObject, resulting in really odd behavior if several objects/classes inherit from parents. Also this only happens if the "deep" extending is used.

I managed to avoid this problem by extending an empty object with the respective prototype and then using the return value of extend as the new prototype. E.g. A.prototype = $.extend(true, {}, A.prototype, {someObject: {extraKey: 'value'}});

To show the problem I created this small jsfiddle: http://jsfiddle.net/x8UtF/12/

The actual question: Is there a way to get around the empty objects and stuff to just go extend(true, X.prototype, {});

Upvotes: 1

Views: 9096

Answers (1)

Šime Vidas
Šime Vidas

Reputation: 185913

So, when you do this:

$.extend( true, A.prototype, {
    someObject: {Aone: 1, Atwo: 2}
});

this will happen as a result:

  1. The properties "Aone", and "Atwo" will be assigned to Parent.prototype.someObject, instead of A.prototype.someObject (which at that point doesn't event exist).
  2. The property A.prototype.someObject will be created and its value will be set to Parent.prototype.someObject.

So, both A.prototype.someObject, and Parent.prototype.someObject will refer to the same object:

A.prototype.someObject === Parent.prototype.someObject // true

This is, of course, not what you want.


That being said, I'm concerned that your pattern is not good. A.prototype is supposed to inherit from Parent.prototype, yet you copy the values from Parent.prototype.someObject to A.prototype.someObject.

Also, your current solution:

A.prototype = $.extend( true, {}, A.prototype, {
    someObject: {Aone: 1, Atwo: 2}
});

is not intuitive. It's not easy to decipher what the code is doing. I recommend re-evaluating that pattern. (You can ask Stack Overflow for help, of course.)

Upvotes: 8

Related Questions