繁体   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