[英]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.