使用require / prototype的节点继承

时间:2013-09-19 23:19:48

标签: javascript node.js

我有一个像这样定义的抽象对象......

var abs = module.exports = function abs(val){

   if(!(this instanceof abs)){

      return new abs(val);

   }

   abs.prototype.getName = function getName(){

      return val.name;

   }

}

和我要继承的具体类,如此定义...

 var concrete = module.exports = function concrete(val){

    var abs = require('./abs');

    if(!(this instanceof concrete)){

       return new concrete(val);

    }

    concrete.prototype = Object.create(abs.prototype);

 }

当我写...

 var anObject { name : "John" };
 var concreteObject = new concrete(anObject);
 concrete.getName();

我收到以下错误..

TypeError: Object #<conrete> has no method 'getName'

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您写的内容中有两个错误(仅留下缺失的=):

  • concrete.getName()不起作用,因为concrete是您的构造函数。它没有这样的方法。
  • concreteObject.getName()不起作用,因为它的原型没有这样的方法。您确实在构造函数中覆盖了concrete.prototype ,但实际上已经使用旧实例构建了实例。检查how the new operator works

因此,您还需要修复这些类定义。正如我们所见,人们无法从共享原型函数中访问构造函数参数 - 它没有任何意义。在构造函数中分配原型方法将使最新val调用的abs可用于所有实例。啊。

使用原型:

function abs(val) {
    if (!(this instanceof abs))
        return new abs(val);

    this.val = val;
}
abs.prototype.getName = function getName(){
    return this.val.name;
};
module.exports = abs;

或使用特权实例方法(请参阅Javascript: Do I need to put this.var for every variable in an object?获取解释):

function abs(val){
    if (!(this instanceof abs))
        return new abs(val);

    this.getName = function getName(){
       return val.name;
    };
}
module.exports = abs;

对于那个concrete的事情,我不明白为什么你需要它 - 它似乎没有比concrete = abs;做的更多。但是,blueprint for inheritance看起来像这样:

var abs = require('./abs');
function concrete(val){
    if (!(this instanceof concrete))
        return new concrete(val);

    abs.call(this, val);
}
concrete.prototype = Object.create(abs.prototype);