【问题标题】:Understanding prototypal inheritance javascript了解原型继承javascript
【发布时间】:2014-06-12 19:25:29
【问题描述】:

这是对这个问题的跟进:Python like inheritance for JavaScript

但我用错了措辞,似乎我想要在 JavaScript 中使用经典继承,而我只是想弄清楚如何与 Python 类似地做到这一点。

这是我目前所拥有的,但它并没有像我希望的那样工作。

var util = require("util")

function FirstClass() {
    this.name = "First Class";
}

FirstClass.prototype.sayName = function(){
    this.callFunction("some_function", "hello")
}

FirstClass.prototype.callFunction = function(){
    var func = arguments[0]; 
    var args = Array.prototype.slice.call(arguments).slice(1, arguments.length)  
    if (this[func] !== undefined){ 
        this[func].apply(null, args); 
    } 
}

function SubClass(){}
util.inherits(SubClass, FirstClass)
SubClass.prototype.some_function = function(msg){
    console.log(msg, this.name) // "hello undefined"
}

var sub_class = new SubClass();
sub_class.sayName();

当我尝试sub_class.sayName() 时,它正确调用并继承了sayName,但是当我尝试使用this 关键字显示名称时,它不起作用并在“hello”旁边打印undefined,所以我将如何解决它,使其显示“你好 FirstClass”?

我在想这包含了 FirstClass 所拥有的所有变量和对象,因为它继承自它,但它没有。原型继承是这样工作的吗?如果是这样,有什么方法可以查看/更改子类中的父变量?

我已经尝试查找 JavaScript 的原型继承来解决这个问题,但我不太了解这个概念,因为我习惯于经典继承。有谁知道如何从父类继承并从子类更改它的变量?

另外,如果有人有一个很好的链接可以查看,那么我可以更好地理解原型继承,以供将来参考。

【问题讨论】:

  • 我也有兴趣知道这个问题的答案。我使用过原型,只是还没有使用继承。
  • @Grimbode:当您使用原型时,您就是在进行继承。
  • @cookie怪物,那么inherits()有什么用呢?
  • 它只是一个帮助函数,在使一个函数的原型对象从另一个函数继承时抽象出一些样板代码。 github.com/joyent/node/blob/master/lib/util.js#L628-L638 但是不管你如何设置原型链,当你将一个成员添加到一个用作另一个原型的对象时,另一个对象会继承该属性。

标签: javascript node.js inheritance


【解决方案1】:

你缺少这部分:

function SubClass(){
   FirstClass.apply(this);
}

这相当于传统类继承中的super 调用。

【讨论】:

  • 谢谢,这成功了。我很惊讶我没有早点发现这似乎很简单。
  • @user3234209:这只是问题的一部分。另一个答案中的null 问题也需要解决。
【解决方案2】:

你的问题在这里:this[func].apply(null, args);

应该是:this[func].apply(this, args);

【讨论】:

  • 我刚改了,还是打印未定义。
  • 我意识到 Edwin 的回答有效,因为我将 null 更改为此,所以这有助于解决我的问题,谢谢。
  • 是的,很高兴能帮到你!感谢您提及这一点。
【解决方案3】:

这是一个关于如何继承和扩展类的简化示例。我非常强烈建议您查看Javascript Design Patterns,以获取有关如何创建具有继承的类的更好示例。

现在,由于我不熟悉 util 应该做什么,这个示例演示了如何使用原生 JS 而不使用辅助函数来实现结果:

JSFiddle 在这里:http://jsfiddle.net/YAj5R/

function FirstClass() {
    this.name = "First Class";
}

FirstClass.prototype.sayName = function () {
    this.callFunction("some_function", "hello")
}

FirstClass.prototype.callFunction = function () {
    var func = arguments[0];
    var args = Array.prototype.slice.call(arguments).slice(1, arguments.length)
    if (this[func] !== undefined) {
        this[func].apply(this, args);
    }
}

function SubClass() {
    var parent = new FirstClass();

    // this is lightweight example of an "extend" method
    for(var attr in parent) {
        // if this subclass has not over-written an attr,
        // copy the attributes of FirstClass to SubClass
        if(!this[attr]) {
            this[attr] = parent[attr];
        }
    }

    return this;
}

SubClass.prototype.some_function = function (msg) {
    console.log(msg, this.name);
}

var sub_class = new SubClass();
sub_class.sayName();

【讨论】:

  • 不过,这种方法可能无法在 FirstClass 中定义任何不可枚举的属性。
  • @user3234209:在实践中你不会想这样做。它首先破坏了使用原型继承的要点,您根本不需要for(var attr in parent) {,并且对FirstClass.prototype 所做的更改不会在SubClass 对象上看到。 util.inherits 主要可以用两行代码替换。
猜你喜欢
  • 2010-10-27
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多