Rocky Singh
Rocky Singh

Reputation: 15430

Want the prototype method to be extended

I have the following code:

    var defaults = {
        test: function () {
            alert('Test');
        }
    };

    function Foo(options) {
        o = $.extend({}, defaults, options);
        Foo.prototype.test = o.test;
    }
    Foo.prototype.test = defaults; 

I want that the test method should be extensible and I want it to be used as:

    var f = new Foo({
        test: function() {
            alert('Test2');
        }
    });

    var f1 = new Foo({
        test: function () {
            alert('Test3');
        }
    });

    f.test();//alert(test2) should be called
    f1.test(); //alert(test3) should be called

Edit: I am not getting what I have written in the comments as the output.

Upvotes: 0

Views: 74

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074178

You're kind of mixing metaphors there. Three options for you:

  • Functional
  • Simple constructor functions, override per instance (what you were trying to do)
  • Reusable prototypical inheritance

Functional

It sounds like you'd like the form of functional inheritance that Douglas Crockford likes, which does away with prototypes in favor of what he calls "maker" functions:

var f = makeFoo({
    test: function() {
        alert('Test2');
    }
});

var f1 = makeFoo({
    test: function () {
        alert('Test3');
    }
});

f.test();
f1.test();

...where makeFoo is:

function makeFoo(options) {
    return $.extend({}, makeFoo.defaults, options);
}
makeFoo.defaults = {
    test: function() {
        alert("Default test");
    }
};

Live example | source

I'm not a huge fan of it myself, but there are many who are and certainly like most things, it has advantages and disadvantages. One of the advantages is how simple it is.

Simple constructor functions, override per instance

But you can do it with constructor functions, much as you tried; you apply the options to this rather than creating your own separate object:

function Foo(options) {
    $.extend(this, options);
}
Foo.prototype.test = function() {
    alert("Default test");
};

var f = new Foo({
    test: function() {
        alert("Test2");
    }
});

var f2 = new Foo({
    test: function() {
        alert("Test3");
    }
});

f.test();
f2.test();

Live example | source

Reusable prototypical inheritance

If you want to go further and have proper hierarchies based on prototypical inheritance (so you can create more than one object with a specific override test function), there's more plumbing to do, but you have the advantage that doing things like calling into a "super"'s version of a function can be quite straight-forward. The plumbing is sufficiently complex that I use a library for it, in my case my own library called Lineage, but Prototype has something similar called Class and there are several others out there.

When doing prototypical inheritance, you have constructor functions and then construct instances with them. The above might look something like this with Lineage:

var ParentFoo = Lineage.define(function(p) {
    p.test = function() {
      alert("Default test");
    };
});

var FooChild1 = Lineage.define(ParentFoo, function(p) {
    p.test = function() {
      alert("Test2");
    };
});

var FooChild2 = Lineage.define(ParentFoo, function(p) {
    p.test = function() {
      alert("Test3");
    };
});

Live example | source

Upvotes: 5

ek_ny
ek_ny

Reputation: 10243

couldn't you just do this?

function Foo(options) {
    o = $.extend({}, defaults, options);
    this.test = o.test;
}

Upvotes: 0

Related Questions