Javascript 继承:调用超级构造函数还是使用原型链? [英] Javascript inheritance: call super-constructor or use prototype chain?
问题描述
最近我读到了关于 MDC 中 JavaScript 调用的使用
Quite recently I read about JavaScript call usage in MDC
https://developer.mozilla.org/en/JavaScript/参考/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();
这有必要吗?因为在
Prod_dept()
反正就是这样
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");
谢谢你让事情更清楚
推荐答案
真正问题的答案是你需要同时做:
The answer to the real question is that you need to do both:
- 将原型设置为父对象的实例会初始化原型链(继承),这仅执行一次(因为原型对象是共享的).
- 调用父对象的构造函数会初始化对象本身,这是在每次实例化时完成的(每次构造它时都可以传递不同的参数).
因此,在设置继承时不应调用父级的构造函数.仅当实例化从另一个继承的对象时.
Therefore, you should not call the parent's constructor when setting up inheritance. Only when instantiating an object that inherits from another.
Chris Morgan 的回答几乎完整,缺少一个小细节(构造函数属性).让我建议一种设置继承的方法.
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
有关创建类时的更多语法糖,请参阅我的博客文章.http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
See my blog post for even further syntactic sugar when creating classes. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
从 Ext-JS 和 http://www.uselesspickles.com/class_library/ 复制的技术以及来自 https://stackoverflow.com/users/1397311/ccnokes
Technique copied from Ext-JS and http://www.uselesspickles.com/class_library/ and a comment from https://stackoverflow.com/users/1397311/ccnokes
这篇关于Javascript 继承:调用超级构造函数还是使用原型链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!