[英]How to implement super mechanism in javascript through prototype?
我正在努力了解Javascript中的构造函数调用模式。 我有一个基础对象Mammal
(使用术语class是不正确的)和一个继承的对象Cat
。 在以下代码中,对象Cat
正确地从哺乳动物对象继承。
/*
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”关键字的机制,以便当以name
为参数调用Cat
的构造函数时,也以name
为参数调用Mammal
的构造函数。
我尝试如下实现Cat
构造函数:
var Cat = function (name) {
this.saying = "Meow";
// Super (name);
this.prototype = new Mammal(name);
}
这不能按预期方式工作。 this.prototype
是未定义的。 为什么? 为什么这种方法是完全错误的? 做this
点新Cat
对象?
我知道,有多种方法可以在javaScript中实现继承,但是我想知道是否有一种方法可以像在Java中那样实现超级机制。
谢谢。 :D
怎么样
var Cat = function (name) {
this.saying = "Meow";
// Super (name);
Mammal.call( this, name );
}
是的,恐怕这不是您设置层次结构的方式。 即将结束,但是有几个关键问题。 (其中一个-调用new Mammal()
创建Cat.prototype
是一个非常非常非常频繁的错误,您会在很多博客文章等中看到)
这是正确执行此操作的简单示例:
// 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中进行继承层次结构,您可能会发现我的Lineage
脚本很有用。 您可能会选择使用它,也可能不会选择使用它,但是它演示了如何进行设置,对父方法的版本(“超级调用”)进行调用的方法等。特别是, 本文档页面将使用Lineage
与不使用它显示了如何在没有任何帮助脚本的情况下执行此操作。 但是我写一个辅助脚本来这样做是有原因的。 :-)
this.prototype
是未定义的,因为没有人定义它。
Cat
是一种功能。 因此,它具有属性prototype
。 这是ECMAScript标准强制要求的。
this
是一个不是功能的对象。 因此,ECMAScript标准并不要求其具有prototype
属性。
如果this
是Cat
(即使用new Cat
创建或创建的对象),则出于规范目的 ,它具有内部[[Prototype]]
属性,该属性为Mamal
。 但是,这种哺乳动物无法直接访问(如内部一词所暗示)。 当您说var maru = new Cat()
, maru.[[Prototype]]
链接到Cat.prototype
。 这就是maru
对未来的哺乳动物方法的了解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.