如何正确设置原型

How to properly set prototype?

本文关键字:原型 设置 何正确      更新时间:2023-09-26

我正在一本名为《面向对象 JavaScript》的书中练习。

第5章的练习包含以下4个问题:

  1. 创建一个名为 shape 的对象,该对象具有 type 属性和 getType() 方法。
  2. 定义一个原型为 shape 的 Triangle() 构造函数。使用 Triangle() 创建的对象应具有三个自己的对象 属性 - a、b 和 c,表示 a 边的长度 三角形。
  3. 向原型添加一个名为 getPerimeter() 的新方法。
  4. 使用以下代码测试您的实现:

.

  var t = new Triangle(1, 2, 3);
  t.constructor === Triangle;  // true
  shape.isPrototypeOf(t);      // true
  t.getPerimeter();            // 6
  t.getType();                 // "triangle"

这是我对上述问题的解决方案:

var shape = {
    type: 'triangle',
    getType: function() {
        return this.type;
    }
};
function Triangle(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
}
Triangle.prototype = shape;  // Maybe something goes wrong here
Triangle.prototype.getPerimeter = function() {
    return this.a + this.b + this.c;
}
// ======================================================
var t = new Triangle(1, 2, 3);              
console.log(t.constructor === Triangle);  // false
console.log(shape.isPrototypeOf(t));      // true
console.log(t.getPerimeter());            // 6
console.log(t.getType());                 // triangle

为什么结果console.log(t.constructor === Triangle);输出false

我尝试删除console.log(t.constructor === Triangle);,这使得t.constructor === Triangle等于true,但会导致TypeError: t.getType is not a function错误。

如何使我的执行结果与本书提供的答案相同?

添加

Triangle.prototype.constructor = Triangle;

Triangle.prototype = shape;

解决了我的问题。

在第6章第173页中,该书说

覆盖原型会对构造函数属性产生副作用。因此,最好在继承后重置构造函数

Shape = {
  type: 'Shape',
  getType: function (){ return this.type;}
}
function Triangle( a, b, c){
    this.a = a;
    this.b = b;
    this.c = c;
    this.type = 'Triangle';
}
Triangle.prototype = Shape; 
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getPerimeter = function (){
  console.log('Get Perimeter');
  return this.a + this.b + this.c;
  
}
var t = new Triangle(1,2,3);
console.log(t.constructor === Triangle);
console.log(Shape.isPrototypeOf(t));      
console.log(t.getPerimeter());            
console.log(t.getType()); 

将 Shap 对象分配给 Triangle.prototype,然后用 Triangle 覆盖构造函数将解决问题。

function Shape() {
  type = "Shape";
 
}
Shape.prototype.getType = function() {
    return "Mi tipo es " + this.type;
  }
function Triangle(a, b, c) {
  Shape.call(this)
  this.a = a;
  this.b = b;
  this.c = c;
  this.type = "Triangle";
}
Triangle.prototype = Object.create(Shape.prototype);
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getPerimeter = function() {
  return this.a + this.b + this.c;
}
var t = new Triangle(1, 2, 3);
console.log(t instanceof Triangle);
console.log(Shape.prototype.isPrototypeOf(t));
t.getPerimeter();
t.getType();