1

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?

cyroxx
  • 3,809
  • 3
  • 23
  • 35
SteveMustafa
  • 621
  • 2
  • 8
  • 19

5 Answers5

2

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.

Community
  • 1
  • 1
cyroxx
  • 3,809
  • 3
  • 23
  • 35
  • So how would the proper way to add/override the function using a prototype? Something like this (http://jsfiddle.net/Mufasaa/zFaU5/4/), but its not working – SteveMustafa Apr 21 '13 at 20:49
1

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

Sachin
  • 40,216
  • 7
  • 90
  • 102
1

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.

0

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);
};
SteveMustafa
  • 621
  • 2
  • 8
  • 19
0
//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.