Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
90
rated 0 times [  93] [ 3]  / answers: 1 / hits: 88790  / 14 Years ago, thu, november 11, 2010, 12:00:00

Quite recently I read about JavaScript call usage in MDC



https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call



one linke of the example shown below, I still don't understand.



Why are they using inheritance here like this



Prod_dept.prototype = new Product();


is this necessary? Because there is a call to the super-constructor in



Prod_dept()


anyway, like this



Product.call


is this just out of common behaviour? When is it better to use call for the super-constructor or use the prototype chain?



function Product(name, value){
this.name = name;
if(value >= 1000)
this.value = 999;
else
this.value = value;
}

function Prod_dept(name, value, dept){
this.dept = dept;
Product.call(this, name, value);
}

Prod_dept.prototype = new Product();

// since 5 is less than 1000, value is set
cheese = new Prod_dept(feta, 5, food);

// since 5000 is above 1000, value will be 999
car = new Prod_dept(honda, 5000, auto);


Thanks for making things clearer


More From » inheritance

 Answers
128

The answer to the real question is that you need to do both:




  • Setting the prototype to an instance of the parent initializes the prototype chain (inheritance), this is done only once (since the prototype object is shared).

  • Calling the parent's constructor initializes the object itself, this is done with every instantiation (you can pass different parameters each time you construct it).



Therefore, you should not call the parent's constructor when setting up inheritance. Only when instantiating an object that inherits from another.



Chris Morgan's answer is almost complete, missing a small detail (constructor property). Let me suggest a method to setup inheritance.



function extend(base, sub) {
// Avoid instantiating the base class just to setup inheritance
// Also, do a recursive merge of two prototypes, so we don't overwrite
// the existing prototype, but still maintain the inheritance chain
// Thanks to @ccnokes
var origProto = sub.prototype;
sub.prototype = Object.create(base.prototype);
for (var key in origProto) {
sub.prototype[key] = origProto[key];
}
// The constructor property was set wrong, let's fix it
Object.defineProperty(sub.prototype, 'constructor', {
enumerable: false,
value: sub
});
}

// Let's try this
function Animal(name) {
this.name = name;
}

Animal.prototype = {
sayMyName: function() {
console.log(this.getWordsToSay() + + this.name);
},
getWordsToSay: function() {
// Abstract
}
}

function Dog(name) {
// Call the parent's constructor
Animal.call(this, name);
}

Dog.prototype = {
getWordsToSay: function(){
return Ruff Ruff;
}
}

// Setup the prototype chain the right way
extend(Animal, Dog);

// Here is where the Dog (and Animal) constructors are called
var dog = new Dog(Lassie);
dog.sayMyName(); // Outputs Ruff Ruff Lassie
console.log(dog instanceof Animal); // true
console.log(dog.constructor); // Dog


See my blog post for even further syntactic sugar when creating classes. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html



Technique copied from Ext-JS and http://www.uselesspickles.com/class_library/ and a comment from https://stackoverflow.com/users/1397311/ccnokes


[#95008] Monday, November 8, 2010, 14 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
janjadonb

Total Points: 4
Total Questions: 114
Total Answers: 118

Location: Mali
Member since Fri, Dec 3, 2021
3 Years ago
janjadonb questions
;