Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use .call vs just adding methods directly to prototype?

There's a Node.js plugin I'm using which implements a pattern that I'd like to better understand.

var Thing = function() {};

(function () {

    this.foo = function() {};
    this.bar = function() {}

}).call(Thing.prototype);

I understand that call is calling the anonymous function with the Thing.prototype context. Does that mean that this.foo is actually being added to Thing's prototype? That's the part that is a little foggy for me if someone could explain.

Also, what would be the advantage of this approach as opposed to just:

Thing.prototype.foo = function() {};
Thing.prototype.bar = function() {};
like image 683
doremi Avatar asked Feb 02 '26 14:02

doremi


1 Answers

In this code:

(function () {

    this.foo = function() {};
    this.bar = function() {}

}).call(Thing.prototype);

call(Thing.prototype) causes the value of this inside the anonymous function to be Thing.prototype so it is setting fields on Thing.prototype. See the documentation for call, but basically the first argument given to call sets the value of this for the function being called, and then the remaining arguments are whatever parameters the function takes. So the code above adds the fields foo and bar to Thing.prototype.

This style of setting fields would allow you to readily declare variables inside the closure if you wanted to. For instance:

(function () {

    var _foo = 0;

    this.foo = function() {
        return _foo;
    };

    this.bar = function() {
        _foo++;
    }

}).call(Thing.prototype);

The _foo variable cannot be directly accessed by anything else than the methods.

It is largely a matter of preference what style one uses. I prefer to use 2nd style in the question:

Thing.prototype.foo = ...

This is mainly because some of the tools I use work better with it. (jsdoc in particular.) And I prefer having ready access to all the fields of my objects.

like image 183
Louis Avatar answered Feb 05 '26 03:02

Louis