Levi Hackwith
Levi Hackwith

Reputation: 9332

How to Use Inheritance in JavaScript with Constructor Methods Returning Object Literals with Private Properties?

var Animal = function(config) {
    config = config || {};
    var name = config.name,
        numLegs = config.numLegs,
        weight = config.weight,
        speed = config.speed,
        sound = config.sound
    return {
        getName: function () {
            return name;
        },
        getNumLegs: function () {
            return numLegs;
        },
        getWeight: function () {
            return weight;
        },
        getSpeed: function () {
            return speed;
        },
        getSound: function () {
            return sound;
        },
        run: function(distance, unit) {
            unit = unit || 'miles';
            return 'The ' + name + ' ran ' + distance + ' ' + unit;
        },
        speak: function() {
            return 'The ' + name + ' says "' + sound + '"';
        }
    }
};

function DragonFly(config) {
    var me = {},
        numWings = config.numWings;
    me.prototype = new Animal(config);
    me.getNumWings = function() {
        return numWings;
    };
    me.fly = function(distance, unit) {
        unit = unit || 'miles';
        return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
    }
    return me;
}

var dragonFly = new DragonFly({
    numWings: 2,
    name: 'DragonFly',
    numLegs: 6
});

Okay, coming from a PHP background, I don't understand inheritance in JavaScript one bit and I'd like some help.

Basically, here's what I'd like to be able to do with an instance of the dragonFly object:

dragonFly.getName(); // 'DragonFly'
dragonFly.fly(1, 'mile'); // 'The dragonfly flew 1 mile';
dragonFly.run(1, 'yard'); // 'The dragonfly ran 1 yard';

I'd also like to know how to override methods and call the parent of those overridden methods. What is wrong with my approach? All the examples above return undefined or throw an error. The main reason I went with the object-literal style is so I could make properties private.

Upvotes: 0

Views: 105

Answers (1)

mpm
mpm

Reputation: 20155

the "fastest" way :

var Animal = function(config) {
config = config || {};
var name = config.name,
    numLegs = config.numLegs,
    weight = config.weight,
    speed = config.speed,
    sound = config.sound
return {
    getName: function () {
        return name;
    },
    getNumLegs: function () {
        return numLegs;
    },
    getWeight: function () {
        return weight;
    },
    getSpeed: function () {
        return speed;
    },
    getSound: function () {
        return sound;
    },
    run: function(distance, unit) {
        unit = unit || 'miles';
        return 'The ' + name + ' ran ' + distance + ' ' + unit;
    },
    speak: function() {
        return 'The ' + name + ' says "' + sound + '"';
    }
   }
};

function DragonFly(config) {
var me = new Animal(config);
var numWings = config.numWings;
me.getNumWings = function() {
    return numWings;
};
me.fly = function(distance, unit) {
    unit = unit || 'miles';
    return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
}
return me;
}

var dragonFly = new DragonFly({
numWings: 2,
name: 'DragonFly',
numLegs: 6
});

You are mixing 2 kind of "inheritance" in your script , the "classical" inheritance and the prototypal inheritance , you cant do that unless you want to be in serious trouble. both work , both have their pros and cons. Stick to the "classical" inheritance , or object augmentation since you began with it.

An object literal doesnt have a prototype , functions have prototypes. That's why in my opinion js isnt "really" object oriented , but it can mimic object oriented langages

A good exercice now would be to try using functions and prototypes , though i'm not sure you could create private fields with that.

Edit : the me.name should be me.getName() since name is "private". i think.

Upvotes: 2

Related Questions