Anonymous vs prototype in jquery

Hi there everyone,

i want to know what is the best one to use, i’m looking for something alone the lines of classes and methods like the way PHP uses it in OOP.

i have started to look this up and the two things i have found was the use of “anonymous” functions:

(function(){
  function foo(){
    //do something
  }

  function bar(){
   // do something
  }
} ());

and javascript’s prototype:

function foo(name){
  this.name = name;
}
foo.prototype.bar = function(){
   return this.name;
 };

This is just a simple example and not any code i’m working with.
So my question is what is better to use, i personally like prototype because it looks like you don’t have to pass the main functions parameters to the prototype (so it’s like extend in PHP class…sort of) but again i like the why the anonymous works as well.

i’m just a bit lost and don’t know what is the best option to take as i am really new to jquery and javascript
Any and all help will be really great :slight_smile: thanks for reading and taking the time.

The first method allows you to have a clean local variable scope. There is a very weird bug or feature of js such that if the preceding js line doesn’t end in a semicolon the anonymous function immediately called technique won’t work. To prevent this use

;(function(){

for the first line. As far as prototypes go, everything, and I do mean everything has a prototype that can be modified - this includes the native objects of the language such as String, Array, even Function. The prototype.js framework makes heavy use of this but it comes at the cost that such code’s behavior around code blocks written by other people is incredibly unreliable. In the long run this is why jQuery beat out prototype.js

Hi @Michael_Morris thank you for the tip :slight_smile: i must have forgot to mention that i’m not talking about the prototype.js lib, i’m talking about the native prototype JS uses

The two approaches in JavaScript are either prototypal inheritance or what’s been dubbed parasitic inheritance.

Prototypal example:

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.prototype.setValue = function (value) {
    this.value = value;
    return this;
};

Parenizor.prototype.getValue = function () {
    return this.value;
};

Parenizor.prototype.toString = function () {
    return '(' + this.getValue() + ')';
};

Parasitic example:

function Parenizor(value) {
    var that = this;
    
    that.setValue = function (value) {
        that.value = value;
        return that;
    });

    that.getValue = function () {
        return that.value;
    });

    that.toString = function () {
        return '(' + that.getValue() + ')';
    });
    
    that.setValue(value);
        
    return that;
}

Some differences:

Parasitic allows truly private members. In prototypal, everything is public; we use a leading underscore to tell users that a member should be treated as if it were private.

In theory, prototypal has a smaller memory footprint at the expense of less speed (and vice versa for parasistic). In theory, the smaller memory footprint is because methods are attached to a single prototype object rather than being attached to each and every instance that’s created. But slower because every method call has to follow a reference to get to the prototype object.

I emphasized “in theory” because JavaScript engines have been heavily optimized in recent years, and neither the speed cost nor the memory cost actually happen anymore.

Given the pros and cons shown here, I think I would favor parasitic inheritance, but there’s another factor that brings me back to prototypal. Future versions of JavaScript will include an explicit class syntax, which is actually just syntactic surgar for the prototypal style. So if you want today’s classes to play nice with tomorrow’s, then I suggest the prototype style.

Hey thank you @Jeff_Mott i was looking it up and found the memory foot print and how people say it’s better in memory then the other options, i will use prototype because i really like the way it’s laid out and if it’s a bit more future proof then it’s good for me to rather start using it.

Thanks again for the help guys. have a great day.

I’ve been trying to adjust to Crockford’s recent preference to do without the this keyword completely. What would that look like in a situation such as this?

The parasitic example, but rather than var that = this;, instead do var that = {}. Then you can call the “constructor” function normally, without the new keyword.

Which is where prototype.js got its name - by making heavy use ( critics say abuse ) of prototypes. Please read more carefully.

Sorry i must have read to fast.

I wanted to also know can i do something like this:

function foo(option){
this.option

 if(this.option == 'number 1'){
  this.bar1(this.option);
 }else if(this.option == 'number 2'){
  this.bar2(this.option);
 }
}

foo.prototype.bar1 = function bar1(){
 return "i'm number 1";
}
foo.prototype.bar2 = function bar2(){
 return "i'm number 2";
}

i would like to know is this ok to use?
I have tested this and it works but i don’t know if there is something wrong with using it like this.

Hey everyone sorry again i saw now from @jeff_mott reply that you can use it in this way :slight_smile: so thank Jeff.
Have great day everyone.

Ok, speaking of reading over things carefully I’ve went back over this thread - there’s a lot of confusion going on. I’m not sure if I’m the one confused or the posters themselves. JavaScript is a cantankerous unusual language, and its implementation of the Object Oriented paradigm is not anything like compiled languages or PHP. Also, several of the examples given display a lack of understanding of javascript scope.

First off, I don’t get the parasitic example of Jeff Mott. I defined it in this html file, and corrected the syntax errors in it to arrive at the code below:

<!DOCTYPE html>
<body>
    Open the Console.
<script>
function Parenizor(value) {
    var that = this;
    
    that.setValue = function (value) {
        that.value = value;
        return that;
    };

    that.getValue = function () {
        return that.value;
    };

    that.toString = function () {
        return '(' + that.getValue() + ')';
    };
    
    that.setValue(value);
        
    return that;
}

ParenizorA = new Parenizor('first object');
console.dir(ParenizorA);
ParenizorB = new Parenizor('second object');
console.dir(ParenizorB);
console.dir(ParenizorA);

Parenizor.prototype.secondValue = 'I am attached after the fact';

console.dir(ParenizorA);
console.dir(ParenizorB);

ParenizorC = new Parenizor('third object');

console.dir(ParenizorC);

console.log(ParenizorA.value);
console.log(ParenizorA.secondValue);

ParenizorA.secondValue = 'Changed';

console.log(ParenizorA.secondValue);
console.log(ParenizorB.secondValue);
console.log(ParenizorC.secondValue);


</script>
</body>
</html>

Yes, you can have private members, but as shown by the last couple of console logs this isn’t the way to do it. I also find the that = this methodology to be sloppy. As for that = {}, this makes separate singleton objects that can’t have prototypes. Also it effectively makes the function a factory method. The ability of prototypical inheritance to effect a change across several objects is one of the most powerful parts of the language, and I strongly recommend avoiding the use of methods which sever this power without reason.

A function called with the new operator has an implicit return of this. Because of this reason you don’t need to issue a return from it. The outer function is essentially the constructor, and the other functions are the methods. Public members and methods are attached directly to the function and private ones are declared locally with var. For example:

<!DOCTYPE html>
<body>
    Open the Console.
<script>
function SampleClass() {
    this.publicVar = 'public';
    var privateVar = 'private';

    this.setValue = function (value) {
        privateVar = value;
    };

    this.getValue = function () {
        return privateVar;
    };

    this.addTheVars = function() {
        return privateVar + this.publicVar;
    };

    var privateMethod = function() {
        return 'I am private ' + privateVar;
    };

    this.testPrivate = function() {
        return privateMethod();
    };

    this.callbackTestA = function() {
        console.log(this.publicVar);
    };

    this.callbackTestB = function() {
        console.log(this.publicVar);
    }.bind(this);
}

var ExampleA = new SampleClass();

console.dir(ExampleA);
console.dir(ExampleA.getValue());
console.log(ExampleA.testPrivate());

var ExampleB = new SampleClass();
ExampleA.setValue('changed private');

console.dir(ExampleA.getValue());
console.dir(ExampleB.getValue());

setTimeout(ExampleA.callbackTestA,1000);
setTimeout(ExampleA.callbackTestB,1000);

</script>
</body>
</html>

This works because all the inner functions are closures as far as javascript is concerned. Because of how scope works in javascript they can see the variables in the same code block the function is declared in. Unfortunately the scope of “this” can be lost if the function is placed in an event callback (as seen in callbackTestA above), so it is sometimes necessary to bind the function scopes to the origin object using bind.

That can become tedious in large objects, so I’ve taken to using this technique.

for ( o in this) {
  if (typeof this[o] === 'function') {
    this[o] = this[o].bind(this);
  }
}

Note the above however doesn’t work on private methods. They will have to be explicitly bound.

EDIT: Note - bind requires an emca5 shim to work on IE 8.

I’m not actually clear what point you meant to make with the last couple of logs. You originally attached secondValue to the prototype, and it’s therefore shared across all instances. Then later you override secondValue on only the A object. So the last couple of console logs seems completely expected to me.

I don’t think it’s right to call it a singleton. The “constructor” function will return a new object every time we invoke it. For it to be a singleton, it would have to return a single, saved instance. But in any case, as for it not having prototypes, yes, that’s correct. The parasitic style favors closures over prototypes to gain features such as private members.

Yes, that’s absolutely correct.

Though, my personal opinion is that this is a feature we should avoid, and for the same reason that we avoid altering the built-in prototypes (Array, Date, etc), because it can lead to unpredictable behavior. The exact same object could behave differently depending on if, and even when, its prototype is altered. I think that kind of unpredictability is bad.

This is one of the reasons why some favor parasitic. Because it uses “that” instead of “this”, so you don’t have to worry about the binding anymore. ParenizorA.toString will always refer to the appropriate instance.

I’m not actually clear what point you meant to make with the last couple of logs.

It is a demonstration of how the language behaves, nothing more.

I don’t think it’s right to call it a singleton. The “constructor” function will return a new object every time we invoke it.

It is an unbound object with no inheritance or prototypes, which in JavaScript is a singleton because you cannot have two copies of given object short of cloning. Yes, the constructor can be called multiple times to create multiple objects, but as far as the language is concerned they are wholly independent. While modern JS engines can cheat away some of the memory loss from doing this, they have their limits.

Though, my personal opinion is that this is a feature we should avoid,
and for the same reason that we avoid altering the built-in prototypes
(Array, Date, etc), because it can lead to unpredictable behavior.

If you choose to limit yourself by refusing to use language features you find confusing that’s your loss - don’t advise others to do the same. There are demonstrable reasons as to why the system prototypes shouldn’t be altered - include the prototype.js library with code not written with it in mind to watch some very entertaining crashes. This interoperability problem is ultimately what doomed prototype.js, even though its syntax is cleaner and easier to use than jQuery, most of the time, at the time both libraries where current. Prototype has fell way behind jQuery though so this is no longer true except in some legacy corner cases (jQuery’s each vs. prototype’s each, the callback receives object, index in prototype, while receiving index, object in jQuery. Most of the time you don’t care about the index, just the object, making jQuery’s implementation less elegant).

As for altering the prototypes of your own objects, there is no reason not to if the situation calls for it. Further, such code can be tested. Saying the behavior of such code is unpredictable is, flatly, a lie. It’s only unpredictable if you do not understand it. Since its your own objects, there shouldn’t be interoperability concerns.

This is one of the reasons why some favor parasitic.

To be blunt, it’s one of the reasons some need to learn how scope works in JavaScript. Avoiding a problem will only get you so far and it creates limitations for the programmer in the long run.

The largest problem JavaScript faces is most of the people writing code for it would rather be using something else, but that isn’t an option since it’s the widespread default of browsers. As a result you see a lot of silly to downright stupid workarounds born of the refusal of the author to come to terms with the language.

Seriously?

I assure you I understand it very well. JavaScript is chock full of features we choose not to use (see JSHint’s options). That doesn’t mean we find them confusing. It’s already widely accepted that we shouldn’t alter the built-in prototypes. All I did was extend the same rule to our own prototypes, and for the same reasons.

I do, however, acknowledge that this isn’t a widely accepted rule. That’s why I made a point to say, “my personal opinion.”

We can understand it and still make it better. Those two are not mutually exclusive. As it is, a lexical “this” is already a new feature coming to JavaScript. But until then, we can simulate it with parasitic and that = this.

That’s not what makes a singleton.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.