1

I'm trying to use a method from a parent class inside the child class. In other languages, you would just have to use extends and all the methods from the parent can be used in the child, but in JavaScript, it seems to be different.

function Svg() {
    this.align = function(value) {
        if(value === 'left') return 0;
    }
}

function Graph() {
    // I want to align text to the left
    console.log('<text x="' + align('left') + '"></text>');
}

graph = new Graph();
Graph.prototype = new Svg();
Graph.prototype.align.call();

http://jsfiddle.net/cBMQg/9/

John Smith
  • 1,750
  • 3
  • 18
  • 31

3 Answers3

1

I do understand that the code below doesn't necessarily 'extend' like in other OOP languages. But it does take another function/class as a property - for which you can call it's methods directly. Furthermore, I haven't used JavaScript prototyping for this demo.

<script>
    function Svg() {
        this.align = function( align ) {
            if( align == 'left') 
                return 'left';
            else
                return 0;
        }
    }

    function Graph() {

        this.Svg = new Svg();
        // I want to align text to the left
        this.AlignLeft = function( direction ) {
            console.log('<text x="' + this.Svg.align( direction ) + '"></text>');
        }
    }

    graph = new Graph();
    graph.AlignLeft('left');  //console.log <text x="left"></text> 
</script>

Fiddle: http://jsfiddle.net/cBMQg/11/

MackieeE
  • 11,751
  • 4
  • 39
  • 56
  • 1
    I don't know why changed it to AlignLeft, apologies! I thought it was for a `text-align` property =)! – MackieeE Oct 06 '13 at 20:46
  • 1
    Why didn't you use prototypes here? They would have been appropriate. Btw, property names are usually lowercased. – Bergi Oct 07 '13 at 14:05
  • Hi Bergie, I'll be very honest and say partly because I've yet to fully grasp prototyping myself. For an example like this question: http://stackoverflow.com/questions/4691044/should-i-use-prototype-or-not where as they seem very valid for both examples - given your experience in JavaScript, I'd love it (and greatly appreciate it!) if you could include in a prototype example, thanks for your comment also - MackieeE =] – MackieeE Oct 07 '13 at 14:15
  • @MackieeE example include, check out the link on more info for prototype. You can copy and paste the code in the console (press F12 in your browser) and run it to see what it does and fiddle with it as much as you want to make sure you understand it. – HMR Oct 07 '13 at 14:38
1
function Svg() {
    this.align = function(value) {
        if(value === 'left') return 0;
    }
}

function Graph() {
     Svg.call(this); // Call the Super Class Constructor with changed THIS
    // I want to align text to the left
    console.log('<text x="' + align('left') + '"></text>');
}



graph = new Graph();
Graph.prototype = new Svg();
graph.align('left');
pnkz
  • 326
  • 4
  • 20
  • 1
    It would be `this.align(…)`. And [don't use `new` for setting up inheritance](http://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here), you should only *call* `Svg` from the `Graph` constructor. – Bergi Oct 07 '13 at 14:05
1

The answers probably work but why no prototype use? Is the align function going to perform different logic on every instance?

As Bergi pointed out; JavaScript uses prototype to inherit and it's better to define members on the prototype that don't change between instances:

Simply explained; prototype can be used to declare members/properties that won't change for an instance. If I declare an object named Person and person has 2 members: name and greet. Greet will output "Hello, I am [this.name]" so greet does not change between instances.

When I declare the greet method on Person prototype and then create thousands of Person instances (ben, jack, mary ....) they will all share only one greet function. This saves memory and cpu time for object intialisation. Check out this link for more info: https://stackoverflow.com/a/16063711/1641941

The following link might help you understand what this refers to in JavaScript. https://stackoverflow.com/a/19068438/1641941

function Svg() {
  this.someInstanceValue=22;
}
Svg.prototype.align = function(value) {
  if(value === 'left') return 0;
}
function Graph() {
    // get Svg's instance properties
    Svg.apply(this,arguments);
    console.log('<text x="' + this.align('left') + '"></text>');
}
//inherit from Svg:
Graph.prototype=Object.create(Svg.prototype);
Graph.prototype.constructor=Graph;

graph = new Graph();

graph.align('left');

If you don't want to inherit from Svg but mix it in then you can still use prototype to mix in it's functions (and call Svg.apply to get needed instance members):

function mixin(source, target){
  for(thing in source){
    if(source.hasOwnProperty(thing)){
      target[thing]=source[thing];
    }
  }
};
function Svg() {
  this.someInstanceValue=22;
}
Svg.prototype.align = function(value) {
  if(value === 'left') return 0;
}
function Graph() {
    // get Svg's instance properties
    Svg.apply(this,arguments);
    console.log('<text x="' + this.align('left') + '"></text>');
}
//mix in Svg:
mixin(Svg.prototype, Graph.prototype)

graph = new Graph();

graph.align('left');
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • thanks HMR! I actually did end up following an aproach much like this. – John Smith Oct 08 '13 at 02:47
  • only difference is I used call instead of apply, I changed that based on your comment on the other answer. I also didn't have this: `Graph.prototype.constructor=Graph;` which I read resets the constructor. – John Smith Oct 08 '13 at 02:52
  • 1
    @JohnSmith The `aplly` instead of `call` can come in handy when you have constructor parameters and just want to pass all of them to the "parent". If you only need to pass certain parameters then you should use `call` Setting the constructor isn't needed for your code to work but others maybe use your code and when they use `newMe=new this.constructor();` then they'll get the wrong object. – HMR Oct 08 '13 at 03:33