在原型继承程序中,当在指定对象中找不到属性时

时间:2013-04-21 08:38:54

标签: javascript

全部,在阅读此post之后,并根据它进行了一些测试。

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

        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 = Object.create(Shape.prototype);

        var rect = new Rectangle();
                    alert(rect.x);

如果我对Shape.call(this);中的代码Rectangle进行了评论,我发现rect.xunderfined而不是0

让我感到困惑的是,我找到了Post的最佳答案:

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

所以我无法理解为什么rect在原型链中找不到xrect已经从Shape继承。如果x中不存在rect,则应该在他的父母中找到它。对 ? 在我的理解中。如果使用Shape.call(this);,它只是向x添加一个新的rect属性,那么,这不会是重用父母原始x的代码。它就像经典继承中的override属性一样。那就是在子类中添加一个新属性,它与基类中的属性具有相同的名称和类型。我不知道我的理解是否正确,如果没有。请纠正我。或者我错过了一些我没注意到的东西?感谢。

修改

以下是基于Thilo和Arun P Johny答案的理解。如果不对,请纠正我。

继承之前。

enter image description here

继承执行后。

enter image description here

因此x仅属于Shape构造的实例。感谢

2 个答案:

答案 0 :(得分:1)

如果您不调用超级构造函数,则不会执行this.x = 0,因此x仍未定义。

如果您希望它出现在原型中,我认为您必须说Shape.prototype.x = 0

  

所以我无法理解为什么rect在原型链中找不到x

这是因为原型也没有x。它只有movex被分配给构造函数中的各个实例(但仅在您调用它时)。

答案 1 :(得分:1)

Arun P Johny是对的(你应该阅读他的评论!)

试试这个:

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

    Shape.prototype.move = function(x, y) {
        this.x += x;
        this.y += y;
        console.log("Shape moved.");
    };


    // Rectangle - subclass
    function Rectangle() {            
    };

    Rectangle.prototype = new Shape();
    var rect = new Rectangle();
    alert(rect.x);

您可以像在代码中那样(注释)调用Shape.call(this);,但这样它不是“真正的”继承,因为您将无法在Rectangle中使用move()

但上面的代码是“新”和原型的混杂,因此非常令人困惑。我想你真正想要做的就是这样:

   var Shape = {
        x: 0,
        y: 0,
        move: function(x, y) {
            this.x += x;
            this.y += y;
            alert("Shape moved: ["+this.x+","+this.y+"]");
        }
    };

    var rect = Object.create(Shape);
    alert(rect.x);
    rect.move(2,3);
    rect.move(1,1);