transilvlad
transilvlad

Reputation: 14532

create an object that extends another

I have an object like this:

var source = (function(undefined) {
    var o;
    function s(o) {
        if(!o || typeof o === 'object') {
            o = o || {};
            o.a = typeof o.a === 'string' ? o.a : 'A';
            o.b = typeof o.b === 'string' ? o.b : 'B';
            this.o = o;
        }
    }
    s.prototype.v = function() {
        // some function
    };
    s.prototype.x = function() {
        // some function
    };
    return s;
})();

I want to use another similar to extend the first.

var extender = (function(undefined) {
    var o;
    function e(o) {
        if(!o || typeof o === 'object') {
            o = o || {};
            o.c = typeof o.c === 'number' ? o.c : 3;
            o.d = typeof o.d === 'number' ? o.d : 4;
            this.o = o;
        }
    }
    e.prototype.y = function(m) {
        // some function
    };
    e.prototype.z = function(m) {
        // some function
    };
    return e;
})();

I can add this.s = new source(o); to the function and with some small changes to my second object can tie everything into the first but I was thinking there might be a better way.

Upvotes: 0

Views: 102

Answers (3)

transilvlad
transilvlad

Reputation: 14532

Check out the following two lines:

e.prototype = source.prototype;

source.call(this, o);

They are the solution.

Of course I had to make some adjustments to the config in order to ensure both operate.

var source = (function(undefined) {
    function s(o) {
        // config
        this.o = {};
        if(!o || typeof o === 'object') {
            o = o || {};
            this.o.a = typeof o.a === 'string' ? o.a : 'A';
            this.o.b = typeof o.b === 'string' ? o.b : 'B';
        }
    }
    s.prototype.x = function(m) {
        console.log(m);
    };
    return s;
})();
var extender = (function(undefined) {
    function e(o) {
        // instanciate parent
        source.call(this, o);
        // child config
        if(!o || typeof o === 'object') {
            o = o || {};
            e = this.o;
            e.c = typeof o.c === 'number' ? o.c : 1;
            e.d = typeof o.d === 'number' ? o.d : 2;
        }
    }
    // inherit
    e.prototype = source.prototype;
    // extend
    e.prototype.y = function(m) {
        console.log(m);
    };
    return e;
})();
var e = new extender({d:3});
console.log(e);

Upvotes: 0

Bergi
Bergi

Reputation: 664589

To combine the snippets from the other two answers to the correct solution, you probably want

var extender = (function(undefined) {
    // var o; - That's useless, `o` is a parameter of the constructor
    function e(o) {
        source.call(this, o); // invoke the `source` constructor on this instance
        o = this.o; // and get the created `o` object
        // …to extend it:
        o.c = typeof o.c === 'number' ? o.c : 3;
        o.d = typeof o.d === 'number' ? o.d : 4;
    }

    // make the prototype a new object inheriting `v` and `x`:
    e.prototype = Object.create(source.prototype);
    // then extend it
    e.prototype.y = function(m) {
        …
    };
    e.prototype.z = function(m) {
        …
    };
    return e;
})();

See docs for Object.create and call.

Upvotes: 1

pvnarula
pvnarula

Reputation: 2831

You can use:-

Object.create(o);//where o is object to inherit from

For cross browser:-

 if (typeof Object.create !== "function")
            Object.create = function(o) {
                function F() {}
                F.prototype = o;
                return new F();
 };

Upvotes: 1

Related Questions