簡體   English   中英

如何通過原型在JavaScript中實現超級機制?

[英]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屬性。

如果thisCat (即使用new Cat創建或創建的對象),則出於規范目的 ,它具有內部[[Prototype]]屬性,該屬性為Mamal 但是,這種哺乳動物無法直接訪問(如內部一詞所暗示)。 當您說var maru = new Cat()maru.[[Prototype]]鏈接到Cat.prototype 這就是maru對未來的哺乳動物方法的了解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM