为什么我们需要在JavaScript中定义构造函数

时间:2014-12-04 21:47:02

标签: javascript constructor

我正在阅读这段代码

// 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.prototype = Shape.prototype,Object.create()做什么特别的事情? 如果Rectangle.prototype.constructor = Rectangle,该怎么办?没被叫?

2 个答案:

答案 0 :(得分:2)

如果您执行Rectangle.prototype = Shape.prototype,那么您在Rectangle.prototoype上执行的任何修改都将反映在Shape.prototype上,因为它们是同一个对象。

为避免这种情况,我们使用Shape.prototype创建一个新对象,使其原型链接指向Object.create(Shape.prototype)

至于Rectangle.prototype.constructor = Rectangle;,是为了确保new Shape().constructor指向Rectangle,而不是Shape

函数的本地prototype具有指向该函数的constructor属性。

e.g。

function Rectangle() {}

Rectangle.prototype.constructor === Rectangle; //true

现在,当我们执行Rectangle.prototype = ...时,我们会破坏该引用,然后需要修复它。

答案 1 :(得分:0)

如果您只是将Rectangle.prototype设置为Shape.prototype,则RectangleShape将共享与原型相同的对象。这意味着,您添加到Rectangle.prototype的所有内容也将在Shape.prototype上提供 - Rectangle将不再继承Shape

Object.create(parent)创建一个从传入的父对象继承的子对象。这样,父对象的所有属性也可供子对象使用,而子对象的属性不会影响父对象。

回答你的问题(“为什么我们需要在JavaScript中定义构造函数?”) - 我们不需要。您也可以只使用普通对象:

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

// Rectangle - subclass
function Rectangle() {
  var rectangle = Shape();
  // rectangle-specific things could be added here
  return rectangle;
}

var rect = Rectangle();

rect instanceof Rectangle; // false, instanceof does not work here
rect instanceof Shape; // false

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