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

在Javascript中创建子类时,为什么要分配prototype字段?,javascript,object,prototype,Javascript,Object,Prototype,假设这是创建对象的好方法: // 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 Rect

假设这是创建对象的好方法:

// 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
对象,称为其属性,等等


那些台词是多余的吗?我缺少什么?

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

如果这些行被注释掉,下面的代码段将写入
rect instanceof Shape

//形状-超类
函数形状(){
这个.x=0;
这个。y=0;
}
//超类方法
Shape.prototype.move=函数(x,y){
这个.x+=x;
这个.y+=y;
console.info('Shape moved');
};
//矩形子类
函数矩形(){
Shape.call(this);//调用超级构造函数。
}
//子类扩展了超类
//注释掉的行:
//Rectangle.prototype=Object.create(Shape.prototype);
//Rectangle.prototype.constructor=矩形;
var rect=新矩形();
矩形的矩形实例;//真的
document.getElementById(“结果”).innerHTML=(形状的rect instanceof).toString()
这一行使您能够将形状对象的原型方法用于矩形对象

var rect = new Rectangle();
rect.move(1, 1); // Outputs, 'Shape moved.'
当您跳过上面提到的行时,这不应该起作用,因为您仍然创建矩形对象,并且您仍然有一个矩形原型,但是您没有使用形状原型作为矩形对象的基本原型,因此没有
Shape.prototype.move

rect instanceof Shape; // true
另外,正如ProgramFOX所说,如果删除上面的行,这一行不会产生
true

以下是包含上述更改的代码段:

//形状-超类
函数形状(){
这个.x=0;
这个。y=0;
}
//超类方法
Shape.prototype.move=函数(x,y){
这个.x+=x;
这个.y+=y;
console.log('形状移动');
};
//矩形子类
函数矩形(){
Shape.call(this);//调用超级构造函数。
}
Rectangle.prototype.doSomething=函数(){
log(“矩形警报”);
}
//子类扩展了超类
//Rectangle.prototype=Object.create(Shape.prototype);
Rectangle.prototype.constructor=矩形;
var rect=新矩形();
console.log(rect instanceof Shape);//不输出true
rect.doSomething();//输出“矩形警报”

直线移动(1,1);//不输出“Shape moved”。
如果没有这些行,测试的工作方式将不同。我建议你重新尝试测试。
TypeError:rect.move不是一个函数
同样,
rect instanceof Shape
false
。你能给我解释一下为什么它是
Shape.call(this)
而不是
Shape(this)
,之所以使用call函数,是因为您希望从矩形构造函数中执行形状构造函数,但将当前对象(矩形!)作为
参数提供给形状构造函数。Call()允许您执行此操作(第一个参数是
this
参数)。因此,矩形也得到了
this.x
this.y
,这是在形状构造函数中实现的,因为
this
对象实际上是赋给
Shape.call(this)
的对象。你能解释一下为什么它是
Shape.call(this)
而不是
Shape(this)吗
?@Imray可能是定义JS规范的人决定这样做的,但我不知道原因。
rect instanceof Shape; // true