suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript – Ein Problem mit bereichssicheren JS-Konstruktoren

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

Dieser Code ist ein Beispiel für P598-599 in JS Height 3.
Was ich fragen möchte, ist, warum die Warnung undefiniert ist?

phpcn_u1582phpcn_u15822853 Tage vor519

Antworte allen(4)Ich werde antworten

  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-19 10:17:29

    开始

    var rect=new Rectangle(5,10);

    进入 Rectangle ,this 指向一个新 object,且叫它 object1

    执行到

    Polygon.call(this,2);

    以 object1 的名义进入 Polygon

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

    object1 的原型是 Rectangle ,所以走到 else

    return new Polygon(sides);

    再次进入 Polygon ,this 指向一个新对象,且叫它为 object2

    object2 的原型是 Polygon ,所以赐予 object2 sidesgetArea

    回到 object1 的地盘, Polygon.call(this,2); 返回 object2 ,然后…… 然后丢掉了。

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

    接着赐予 object1 undefinedwidthheightgetArea

    最后,rect 得到了 object1

    补上解决方案,让 Rectangle 共用 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

    Antwort
    0
  • 淡淡烟草味

    淡淡烟草味2017-05-19 10:17:29

    在Rectangle中将Polygon的this指向了Rectangle的this,Rectangle作为构造函数使用时this指的是Rectangle的实例,即本例中的rect,而Polygon的原型并没有在rect的原型链上,即this instanceof Polygon为false,所以走的是else内的return new Polygon(sides),没有将sides挂到实例上,所以rect实例上也就不存在sides属性。
    还有Rectangle(wifth,height),width写错了

    Antwort
    0
  • 習慣沉默

    習慣沉默2017-05-19 10:17:29

    在你的例子中,Polygon 就是个干扰项,对 Rectangle 一点影响都没有。

    去掉 Polygon.call(this,2); 再看,能明白原因了么

    Antwort
    0
  • 巴扎黑

    巴扎黑2017-05-19 10:17:29

    • 打印一下this,你就知道原因了

    • this.sides=sides 挂在了Polygon

    • return new Polygon(sides);//this 不再是调用的时候的Rectangle

    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); 

    Antwort
    0
  • StornierenAntwort