javascript - A problem with js scope-safe constructors
phpcn_u1582
phpcn_u1582 2017-05-19 10:15:29
0
4
467
function Polygon(sides){
                if(this instanceof Polygon){
                    this.sides=sides;
                    this.getArea=function(){
                        return 0;
                    }
                }else{
                    return new Polygon(sides);
                }
            }
            
            function  Rectangle(wifth,height){
                Polygon.call(this,2);
                this.width=this.width;
                this.height=height;
                this.getArea=function(){
                    return this.width * this.height;
                };
            }
            
            var rect=new Rectangle(5,10);
            alert(rect.sides); //undefined

This code is an example of P598-599 in JS Elevation 3
What I want to ask is why the alert is undefined?

phpcn_u1582
phpcn_u1582

reply all(4)
曾经蜡笔没有小新

Start

var rect=new Rectangle(5,10);

Enter Rectangle, this points to a new object, and call it object1

Executed to

Polygon.call(this,2);

Enter Polygon in the name of object1

           function Polygon(sides){
                if(this instanceof Polygon){
                    this.sides=sides;
                    this.getArea=function(){
                        return 0;
                    }
                }else{
                    return new Polygon(sides);
                }
            }
The prototype of

object1 is Rectangle, so go to else

return new Polygon(sides);

Enter Polygon again, this points to a new object, and call it object2

The prototype of

object2 is Polygon, so object2 is given sidesgetArea

Return to object1's territory, Polygon.call(this,2);Return to object2, and then... Then throw it away.

            function  Rectangle(wifth,height){
                Polygon.call(this,2);
                this.width=this.width;
                this.height=height;
                this.getArea=function(){
                    return this.width * this.height;
                };
            }

Then give object1 undefinedwidthheightgetArea .

Finally, rect got object1

Add the solution and let Rectangle share the prototype of Polygon

function Rectangle(wifth,height){
    Polygon.call(this,2);
    this.width=width;
    this.height=height;
    this.getArea=function(){
        return this.width * this.height;
    };
}
Rectangle.prototype = Polygon.prototype
淡淡烟草味

In Rectangle, point Polygon's this to Rectangle's this. When Rectangle is used as a constructor, this refers to the instance of Rectangle, that is, rect in this example, and the prototype of Polygon is not on the prototype chain of rect, that is, this instanceof Polygon is false, so the return new Polygon(sides) in else is used, and sides is not attached to the instance, so the sides attribute does not exist on the rect instance.
There is also Rectangle(with,height), width is written wrong

習慣沉默

In your example, Polygon is an interference item and has no effect on Rectangle at all.

Remove Polygon.call(this,2);Look again, can you understand the reason

巴扎黑
  • Print this and you will know the reason

  • this.sides=sides is hung on Polygon

  • return new Polygon(sides);//this is no longer the Rectangle when called

function Polygon(sides){
                if(this instanceof Polygon){
                    this.sides=sides;//sides
                    console.log(this)
                    this.getArea=function(){
                        return 0;
                    }
                }else{
                    console.log('Polygon'+this)
                    return new Polygon(sides);
                }
            }
            
            function  Rectangle(wifth,height){
                Polygon.call(this,2);
                console.log(this)
                this.width=this.width;
                this.height=height;
                this.getArea=function(){
                    return this.width * this.height;
                };
            }
            
            var rect=new Rectangle(5,10);
            alert(rect.sides); 
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template