问题描述
我很难理解Javascript中的构造函数调用模式。
我有一个基础对象 Mammal
(使用术语类?是不正确的)和继承的对象 Cat
。在下面的代码中,对象 Cat
正确地继承了Mammal对象。
I am struggling to understand the constructor invocation pattern in Javascript.I have a base object Mammal
( would it be incorrect to use the term class ? ) and an inherited object Cat
. In the following code the object Cat
correctly inherits from the Mammal object.
/*
Mammal base Object
*/
var Mammal = function(name) {
this.name = name;
}
Mammal.prototype.get_name = function() {
return this.name;
}
Mammal.prototype.says = function () {
return this.saying || '';
}
/*
Cat object
*/
var Cat = function (name) {
this.saying = "Meow";
this.name = name;
}
Cat.prototype.purr = function (number) {
var i =0, s='';
for ( i=0; i<number; i++)
if (s)
s +='-';
s+='r';
return s;
}
Cat.prototype = new Mammal();
console.log("Pseudo classical inheritance approach");
var mammal = new Mammal(" I am a mammal");
console.log("Who are you ? " + mammal.get_name());
console.log("What are you saying? " + mammal.says());
var cat = new Cat('I am a cat');
console.log("Who are you ? " + cat.get_name());
console.log("What are you saying? " + cat.says());
我不喜欢这个模式是如何使用基础对象的构造函数。对象 Cat
不能正确重用基类 Mammal
的构造函数。我想有更多的灵活性。每次创建一个 Cat
对象时,将调用不带参数的 Mammal
对象的构造函数。我想使用类似于Java中的super关键字的机制,当 Cat
的构造函数使用 name
作为参数,还使用 name
作为参数调用 Mammal
的构造函数。
What I don't like in this pattern is how the constructor of the base object is used. The object Cat
does not reuse correctly the constructor of the base class Mammal
. I would like to have a more flexibility. Each time a Cat
object is created, the constructor of the Mammal
object is invoked with no arguments. I would like to use a mechanism similar to the "super" keyword in Java, so that when the constructor of Cat
is called with name
as parameter, also the constructor of Mammal
is called with name
as parameter.
我尝试实现 Cat
构造函数,如下所示:
I tried to implement the Cat
constructor as follows :
var Cat = function (name) {
this.saying = "Meow";
// Super (name);
this.prototype = new Mammal(name);
}
这不能按预期工作。 this.prototype
未定义。为什么?为什么这种方法是完全错误的? 这个
指向新的 Cat
对象?
This does not work as expected. this.prototype
is undefined. why? Why this approach is completely wrong? does this
point to the newly Cat
object?
我知道,有不同的方法在javaScript中实现继承,但我想知道是否有一种方法来实现像Java中的超级机制。
I know, there are different ways to implement inheritance in javaScript, but I am wondering if there is a way to implement the super mechanism like in Java.
谢谢。 :D
推荐答案
是的,恐怕不是如何设置层次结构。它接近,但有几个关键问题。 (其中一个<—调用 new Mammal()
创建 Cat.prototype
— ,
Yes, I'm afraid that's not how you set up hierarchies. It's close, but there are a couple of key issues. (One of which — calling new Mammal()
to create Cat.prototype
— is a very, very, very frequent error you see in a lot of blog posts and such.)
这是一个简单的例子:
// A function to set up the link between a child and parent
function derive(Child, Parent) {
// `ctor` is a temporary function we use so we can get an object
// backed by `Parent.prototype` but without calling `Parent`.
function ctor() { }
// Borrow the prototype
ctor.prototype = Parent.prototype;
// Create an object backed by `Parent.prototype` and use it as
// `Child`'s prototype
Child.prototype = new ctor();
// Some housekeeping to make the prototype look like the ones
// the JavaScript engine creates normally.
Child.prototype.constructor = Child;
// Note: If we can rely on ES5 features, we could use
// `Object.create` instead of the `ctor` function.
}
// The parent constructor
var Mammal = function(name) {
this.name = name;
};
// Some stuff for its prototype
Mammal.prototype.get_name = function() {
return this.name;
};
Mammal.prototype.says = function () {
return this.saying || '';
};
// The child constructor
var Cat = function(name) {
Mammal.call(this, name);
this.saying = "Meow";
};
// Hook it up to the parent
derive(Cat, Mammal);
// Add some things to its prototype
Cat.prototype.purr = function (number) {
var i =0, s='';
for ( i=0; i<number; i++)
if (s)
s +='-';
s+='r';
return s;
};
如果你有兴趣在JavaScript中做继承层次结构,你可能会发现我的有用。你可能或可能不会选择使用它,但它演示了如何设置的东西,一种方法来调用父的版本的方法(supercalls)等。特别是,使用沿袭
比较不使用它显示如何没有任何帮助脚本这样做。但是有一个原因我写了一个帮助脚本来做。 : - )
If you're interested in doing inheritance hierarchies in JavaScript, you may find my Lineage
script useful. You may or may not choose to use it, but it demonstrates how to set things up, a way to do calls to the parent's version of methods ("supercalls"), etc. In particular, this documentation page comparing using Lineage
to not using it shows how to do this without any helper script. But there's a reason I wrote a helper script to do it. :-)
这篇关于如何通过原型在javascript中实现超级机制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!