【问题标题】:JavaScript Polymorphism variable inheritanceJavaScript 多态变量继承
【发布时间】:2013-01-14 03:15:33
【问题描述】:

我正在根据我在网上找到的不同示例在 JavaScript 中练习多态性(第一次尝试)。我知道在其他语言中我可以从扩展的超类中访问超类的变量,并且想知道如何在 JavaScript 中正确执行此操作。下面的代码不会抛出任何错误(至少就 Firefox 的错误控制台而言),但 statement 在 ExtendedClass 中未定义。

function MyClass() {
  this.statement = "I'm a class with a method";
  this.speak = function() {
    alert(this.statement);
  }
}
var mInstance = new MyClass();
mInstance.speak();

function ExtendedClass() {
  Object.create(MyClass);
  this.speak = function() {
    alert(this.statement+" and I extend a class");
  }
}
var eInstance = new ExtendedClass();
eInstance.speak();

我可以从ExtendedClass 访问statement 吗?这是实现多态的好方法吗?

【问题讨论】:

    标签: javascript polymorphism


    【解决方案1】:

    可以使用MyClass.call(this)设置局部变量,然后使用Object.create设置原型,像这样

    function MyClass() {
      this.statement = "I'm a class with a method";
      this.speak = function() {
        alert(this.statement);
      }
    }
    var mInstance = new MyClass();
    mInstance.speak();
    
    function ExtendedClass() {
      MyClass.call(this);
      this.speak = function() {
        alert(this.statement+" and I extend a class");
      }
    }
    ExtendedClass.prototype = Object.create(MyClass.prototype);
    var eInstance = new ExtendedClass();
    eInstance.speak();
    

    您可以在MDN Docs查看更多信息

    【讨论】:

    • 这看起来就像 RyanFishman 的答案,但里面也有 ExtendedClass.prototype = Object.create(MyClass.prototype);,这是做什么的?我不习惯使用prototype 或Object.create()
    • 是的,我们同时发布。这篇文章可能有助于给出一个详细的解释:benmccormick.org/blog/2013/01/12/…,但简短的解释是 Javascript 继承与经典继承的工作方式不同。对象有一个“原型链”,它们可以与其他对象共享。所有对象默认共享 Object.prototype 原型,也可以共享其他对象的原型,如上图。我链接的 MDN 文章也解释了这一点。
    • 啊,对不起,我应该换个说法,我并不是要建议你在看到他的答案后写下你的答案。谢谢
    • 只是仔细检查,多出来的那一行是为了更正ExtendedClass的构造函数指针?
    • 不完全是。函数 ExtendedClass() 是 ExtendedClass 类型的构造函数。 ExtendedCLass.prototype 是对 ExtendedClass 类型原型链的引用,这就是在 javascript 中控制继承的方式。它在 javascript 或 C++ 等语言中没有完全相同的等价物,因为这些语言使用经典继承而不是原型继承。
    【解决方案2】:

    我是这样做的

    function MyClass() {
      this.statement = "I'm a class with a method";
      this.speak = function() {
        alert(this.statement);
      }
    }
    var mInstance = new MyClass();
    mInstance.speak();
    
    function ExtendedClass() {
      MyClass.call(this);
      this.speak = function() {
        alert(this.statement+" and I extend a class");
      }
    }
    var eInstance = new ExtendedClass();
    eInstance.speak();
    

    不确定这是否是最好的语法,但我知道这是可行的,并且您可以正确继承 MyClass 及其所有公共方法和变量。

    【讨论】:

      【解决方案3】:

      Prototypes 是您正在寻找的。​​p>

      var MyClass = function(){}; //Empty Constructor
      MyClass.prototype = {
          statement: "I'm a class with a method",
          speak: function(){
              alert(this.statement);
          }
      };
      var ExtendedClass = function(){}; //Empty Constructor
      ExtendedClass.prototype = new MyClass();
      ExtendedClass.prototype.speak = function(){
          alert(this.statement+" and I extend a class");
      };
      var eInstance = new ExtendedClass();
      eInstance.speak();
      

      【讨论】:

      • 这是创建ExtendedClass 的不同方式吗?语法看起来不像我所知道的语言中的类声明
      • 是的,Javascript 的 OOP 和继承风格是非传统的(说得好听点)。在不使用 call 方法的情况下,这几乎是我能得到的最简洁的。不知道为什么,我只是不喜欢使用方法来实际继承其他对象的属性和方法。这一切都归结为您的个人偏好,以及它对您的可读性。
      • 我只是尝试复制/粘贴它来尝试它,因为它看起来与其他的非常不同,但它会引发错误:MyClass is not defined
      • 我很抱歉。我忘了在原始代码中定义实际的对象。更新了一个经过测试的工作示例。
      • 感谢您修复它。我想我暂时还是会坚持那些看起来像 Java 的,但是看到更多的例子是件好事
      猜你喜欢
      • 1970-01-01
      • 2014-07-26
      • 2016-09-10
      • 2017-01-10
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多