【问题标题】:Method inheritance in the JavaScript prototype chainJavaScript 原型链中的方法继承
【发布时间】:2013-05-09 19:23:20
【问题描述】:

"在 javascript 中,每个对象都有一个指向创建它的对象的秘密链接,形成一个链。当一个对象被要求提供它没有的属性时,它的父对象被询问......不断直到找到属性或到达根对象为止。"

所有,我现在一直认为上面的话是真的,所以我做了一些测试来验证它,我打算像下面这样定义对象的关系。请检查一下。

代码应如下所示。

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

        Shape.prototype.move = function(x, y) {
            this.x += x;
            this.y += y;

            alert('Shape move');
        };

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

        Rectangle.prototype.move = function(x, y) {
            this.x += x;
            this.y += y;

            alert('Rectangle move');
        };

        // Square - subclass
        function Square(){
            Shape.call(this);
        }

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

        var rect = new Rectangle();

        var sq= new Square();

        sq.x=1;
        sq.y=1;
        sq.move(1,1);

由于在Square.prototype中找不到move方法,所以JavaScript会在它的父对象链中找到,我原以为会在Rectangle.prototype中找到,但实际上是在根 Shape.prototype 中找到,所以我无法理解的是为什么 sq.move(1,1) 实际调用 Shape.prototype.move 而不是调用 moveRectangle.prototype 方法?我错过了什么吗?谢谢。

【问题讨论】:

  • 应该Square() 构造函数调用Rectangle() 而不是Shape()
  • 因为 SquareShape 子类而不是 Rectangle 子类 (?)
  • @All 让我试试,我觉得不是问题。
  • Retangle.prototype = new Shape() 不是比使用Object.create() 更容易吗?
  • @All ,call 方法只是调用constructor,与prototype 对象无关。顺便说一句,通常继承链总是关于对象的prototypeconstructor 仅用于构造创建的对象。

标签: javascript javascript-objects


【解决方案1】:

你刚刚覆盖了你的Rectangle.prototype,它已经有move。既然你已经覆盖了,你附加的move就没有了,所以才用Shape的招式。

Rectangle.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  alert('Rectangle move');
};

function Square(){
  Shape.call(this);
}

//overwritten the prototype
Rectangle.prototype = Object.create(Shape.prototype);

先创建原型对象,然后再添加。

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.move = function (x, y) {
  this.x += x;
  this.y += y;
  alert('Rectangle move');
};

【讨论】:

  • 这与吊装无关;代码只是覆盖Rectangle.prototype :)
  • @Jack 哦,是的。他的代码非常复杂,我最初认为是这样。谢谢
  • @JosephtheDreamer 现在我知道原因了! Object.create 会将另一个实例分配给Rectangle.prototype,所以在我的代码中,move 方法在Rectangle.prototype 中不再存在,因为还有另一个对象覆盖了之前的对象。希望你验证我的理解。谢谢。
  • override ----> overwrite 抱歉打错了。
【解决方案2】:

向下移动原型的扩展。 现在您在扩展原型后分配原型,因此它将覆盖扩展的原型

//Shape - superclass
        function Shape() {
          this.x = 0;
          this.y = 0;
        };
        // Rectangle - subclass
        function Rectangle() {
          Shape.call(this); //call super constructor.
        }
        // Square - subclass
        function Square(){
            Shape.call(this);
        }    

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

        Shape.prototype.move = function(x, y) {
            this.x += x;
            this.y += y;

            alert('Shape move');
        };
        Rectangle.prototype.move = function(x, y) {
            this.x += x;
            this.y += y;

            alert('Rectangle move');
        };

        var rect = new Rectangle();
        var sq = new Square();

        sq.x=1;
        sq.y=1;
        sq.move(1,1);

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2016-07-29
    • 2016-04-03
    • 1970-01-01
    • 2010-09-28
    • 2010-09-28
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多