3

As a c#/.net dev, I love to toy around with JavaScript in my spare time -- creating my own libraries/frameworks and such. Admittedly, they're not much (really nothing more than a loose collections of functions), but the purpose is to learn; not for other people to use.

I usually extend a basic JavaScript object this way

obj = function () {
    //basic object stuff
    this.method = function () {
        //other stuff
    };
    return this;
};

This allows me to create other objects and chain methods together, which is really slick:

obj('arg1').method();

Two Examples: jQuery Knock-off, List-Item Sorter

However, I have recently seen, in much more function code than my own, objects accomplish the same functionality this way:

function obj(){
    //stuff
}
obj.prototype.method = function () {
    //stuff
};

Example: Reddit Chrome Extension

Both ways seem to accomplish the same end, and I'm not partial to the look of either syntax. Is there a particular situation where one would be more useful than the other? What do these methods offer that makes them more desirable than the other?

Edit

Consider the following code:

var dice = function (sides) {
    this.roll(){
        return 4 //guaranteed to be random
    }
};

var d1 = dice(6);
d1.roll()  // 4;
var d2 = dice(20);
d2.roll()  // 4

Are d1 and d2 different objects, as they appear to me? Or are they pointers/nicknames to one object (var dice)?

Michael Jasper
  • 7,962
  • 4
  • 40
  • 60
  • possible duplicate of [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Pablo Fernandez Aug 02 '11 at 21:12
  • 1
    FYI: Your first example works because you're actually creating `method` on the global `window` object, and then returning the global. (Unless you've excluded some key code that changes its meaning). Your `dice` example won't work at all because of invalid syntax and fixing the syntax, `d1` and `d2` will be `undefined`. – user113716 Aug 02 '11 at 21:21

1 Answers1

13
this.method = function(){};

Only works for that specific instance.

Obj.prototype.method = function(){};

Will work for every instance of Obj

Though in order to take advantage of prototype you should do

var o = new Obj(); // Note that functions intended to be used with "new" should be capitalized

o.method();

Dice Example

I'll assume you intended to return this in your dice() function.

That example is not really common, because calling a function does not create a new object. In your dice case you would be assigning a method to this, which inside the function is window the global object, and then returning it.

The outcome would be the same object (window) in both d1 and d2, with a method roll which would be reassigned in the 2nd call.

To achieve what you want you should create the instances with new, like this:

var d1 = new Dice(6); // remember capitalization is important here
var d2 = new Dice(20); 

This will however create 2 roll functions, which is correct but wastes memory since the function can be shared by doing:

Dice.prototype.roll = function() { /* return random awesomeness */ };

Hope that clarifies things

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
  • 1
    If he gave his first function a name and used it as a constructor there would be no difference though, right? – Dan Aug 02 '11 at 21:02
  • Yes there would be. The `method` won't be shared, you would be effectively creating a new function for each new object, wasting memory. There wouldn't be a difference in behavior though – Pablo Fernandez Aug 02 '11 at 21:04
  • @Michael could you edit your question with this extra code? It's hard to read (and answer) it here – Pablo Fernandez Aug 02 '11 at 21:11