在Javascript中创建子类时,为什么要分配原型字段?

时间:2014-10-26 17:11:29

标签: javascript object prototype

Mozilla's Javascript docs说这是创建对象的好方法:

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle; // true
rect instanceof Shape; // true

rect.move(1, 1); // Outputs, 'Shape moved.'

然而,在练习时,我故意跳过这些行

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

所有的行为似乎都很正常。似乎没有跳过这些线的后果。例如,我仍然创建了Rectangle个对象,称为其属性等。

这些线条是多余的吗?我错过了什么?

2 个答案:

答案 0 :(得分:4)

Rectangle.prototype = Object.create(Shape.prototype);

这一行使您可以将Shape对象的原型方法与Rectangle对象一起使用。

var rect = new Rectangle();
rect.move(1, 1); // Outputs, 'Shape moved.'

当你跳过上面提到的那行时,这应该不起作用,因为你仍然创建了Rectangle对象,并且你仍然有一个Rectangle原型,但是你没有使用Shape的原型作为Rectangle对象的基本原型,也不是结果没有Shape.prototype.move应该可用。

rect instanceof Shape; // true

此外,正如ProgramFOX所说,如果您删除上述行,此行不会产生true

以下是带有上述更改的摘录:

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.log('Shape moved.');
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

Rectangle.prototype.doSomething = function() {
    console.log('Rectangle alert.');
}

// subclass extends superclass
//Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log(rect instanceof Shape); // Does NOT output true
rect.doSomething(); // DOES output 'Rectangle alert.'
rect.move(1, 1); // Does NOT output 'Shape moved.'

答案 1 :(得分:2)

如果删除这些行,rect instanceof Shape将返回false

如果这些行被注释掉,则以下代码段会写rect instanceof Shape

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
// lines commented out:
//Rectangle.prototype = Object.create(Shape.prototype);
//Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle; // true
document.getElementById("result").innerHTML = (rect instanceof Shape).toString();
<div id="result"></div>