简体   繁体   中英

Javascript OOP prototype inheritance

I'm trying to practice JS OOP, particularly prototype inheritance, and I can't figure out why this JS Fiddle is returning undefined. Code below:

function Shape(name, edges) {
    this.Name = name;
    this.Edges = edges;
}

Shape.prototype.toString = function(){ return "Shape: " + this.Name;};

function Circle(radius) {
    this.Radius = radius;
}

Circle.prototype.Area = function(){
    return Math.PI * Math.pow(this.Radius, 2);
};

Circle.prototype = new Shape("Circle", 1);
Circle.prototype.constructor = Circle;

var circle = new Circle(5);

console.log(circle);
console.log(circle.toString());
console.log(circle.Area);

Could anyone shed some light on this please?

Executing your code, I get the following output:

Circle { Radius=5, Name="Circle", Edges=1 }
Shape: Circle
function()

So, there is no undefined here. However, I can imagine you wanted to see the calculated area be printed on the console instead of function() .

This can be done by actually calling the Area function, like so:

console.log(circle.Area());

After making this modification (see JSFiddle ), you get the correct result:

78.53981633974483

Explanation: In your implementation, you were only accessing the function object, which printed function() , instead of calling the function, which really calculates the desired value.

EDIT

As from your comment, I believe your question is a duplicate of this one . From the details given in this answer , I was able to get the following working:

function Circle(radius) {
    this.Name = "Circle";
    this.Edges = 1;
    this.Radius = radius;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;

Circle.prototype.Area = function () {
    return Math.PI * Math.pow(this.Radius, 2);
};

However, my JS skills are limited, so this might have a flaw or two. For more advanced inheritance, you may take a look at the accepted answer in the question I referenced above for hints on frameworks that would be worth using.

If you are calling Area function to get the area of circle then you need to call it like this

console.log(circle.Area())

JS Fiddle

None of your logs show undefined .

If you're testing in your developer's console, you'll find a final return value at the end of your input. This value is often undefined , and has nothing to do with your code.

I figured it out.

But its with thanks to everyone on this thread actually. It took a while for it dawn on me and its actually a rookie mistake.

I assigned the prototype function Area to object circle, before inheriting the base Shape prototype.

The section in question is now like so:

function Circle(radius) {
    this.Radius = radius;
}


Circle.prototype = new Shape("Circle", 1);
Circle.prototype.constructor = Circle;

Circle.prototype.Area = function () {
    return Math.PI * Math.pow(this.Radius, 2);
};
//creating the main Object variables with static Propertys
var MySystem={
    Utility:{},
    AppDbSystem:{
        connecterObj:"",
        objCollection:new Array(),
        sendObjCollection:null,
        phpGridCollection:null
    },
    OutManager:{},
    DbIndex:{},
    GoDb:{},
    Ioform:{},
    ListView:{},
    WindowSystem:{},
    AngularSystem:{
        objCollection:null
    }
}

//the parent class (top of the chain)
MySystem.GoDb.GoDb=function(){
    var that=this;
    this.namespace;
    this.speicher;

    this.initGoDb=function(table,group,indexArr,readOnly){
        that.speicher=table;
    }

    this.showS=function(){
        alert(that.speicher);
    }

    this.setNamespace=function(ns){
        that.namespace=ns;
    }
    this.getNamespace=function(){
        return that.namespace;
    }
}

//ListView second Class of the Chain
MySystem.ListView.ListView=function(){
    var that=this;
    MySystem.GoDb.GoDb.apply(this); //IMPORTANT to make it as an Instance

    this.initListView=function(submitIndex,idArr,methodActionArr){
        that.initGoDb(submitIndex);
    }
}
MySystem.ListView.ListView.prototype=new MySystem.GoDb.GoDb();

//The Child Class
MySystem.ListView.ListStandard=function(){
    var that=this;
    MySystem.ListView.ListView.apply(this);


    this.init=function(elementYArr,attrs,methodActionArr,idArr,tableId,styleArr,styleArrTr,styleArrTd,withNumbers,submitIndex){
        that.initListView(elementYArr);
    }
}
MySystem.ListView.ListStandard.prototype=new MySystem.ListView.ListView();

//now use it
var test=new MySystem.ListView.ListStandard();
var test2=new MySystem.ListView.ListStandard();
test.init("eazy");
test.showS();
test2.init("second obj");
test2.showS();
test.showS();

Look at http://www.zipcon.net/~swhite/docs/computers/languages/object_oriented_JS/inheritance.html

And dont forget to do the apply call.

MySystem.ListView.ListView.apply(this);

Otherwise the Object propertys are static and not inheritable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM