理解JavaScript继承

时间:2014-03-24 05:59:52

标签: javascript inheritance prototype

Block = function (){
 this.type = 'block';
 if(arguments[0]) this.type = arguments[0];

 this.location = {x: 0, y: 0};
 function update(){

   }
}

Empty = function(location){
this.prototype = new Block;

this.type = 'empty';
this.location = location;
}

我希望能够致电

var x = new Empty();
x.update();

但是我得到x.update不是函数的错误。

2 个答案:

答案 0 :(得分:2)

prototype属性仅对函数有用。在Empty构造函数中,您在每个Empty实例上设置它,因此它基本上什么都不做。

使用JavaScript进行继承比使用JavaScript更好的方法是将继承类的原型设置为从基类的原型继承:

Empty.prototype = Object.create(Block.prototype);

...并且为了继承基类构造函数中设置的属性,只需在继承类构造函数中使用正确的参数调用它:

Empty = function(location) {
  Block.call(this, location); // call base class
  // other code, specific to your inheriting class
}

请注意,在定义Empty:

之后应该出现Empty.prototype行
Empty = function(location) {
  Block.call(this, location); // call base class
  // other code, specific to your inheriting class
}
Empty.prototype = Object.create(Block.prototype);

最后,要使方法可用于实例,您可以在每个实例的构造函数中定义它们:

Block = function() {
  this.update = function() { };
}

...或者在构造函数的原型上(显然是在定义了构造函数之后):

Block.prototype.update = function() {};

我不知道你的特殊情况,但在我看来你的继承有点奇怪。通常,基类是更通用的类型(具有可变位置),并且继承类专门化它。基类是医生(治疗疾病的人),继承阶级是牙医(治疗某些疾病的人)。

答案 1 :(得分:0)

你没有在构造函数中设置this的原型(它指向新对象,它没有任何含义的原型属性),你直接在构造函数上设置它(在这种情况下Block。)

此外,您的案例中update 隐藏。你需要将它分配给this(不是那么好的做法)或者让它成为Block原型的一部分,你应该这样做,否则在这里没有使用委托或继承的真正意义。

您的代码应该看起来或多或少......

var Block = function () {
    this.type = 'block';
    if (arguments[0]) this.type = arguments[0];
    this.location = {
        x: 0,
        y: 0
    };
};

Block.prototype.update = function () {
    console.log("updating");
};

var Empty = function (location) {
    this.type = 'empty';
    this.location = location;
};

Empty.prototype = new Block;

var x = new Empty();
x.update();

jsFiddle