38

Object literal=name value pairs wrapped in curly braces.

Constructor=a function used to create multiple instance using keyword new.

Prototype=for extension of a literal.

This is what I have understood till now.But the more I research,More I get confused about what is the significance of each one of them. I have used constructor,protoypes and literals in my code a few times.But everytime I use them,I feel like I am still not aware of the full potential of it.I want to go one step ahead of being a begineer now.I hope Folks at stackoverflow help me achieve it

  1. Which is the best preferred way of programming(object literals vs constructors vs prototype)

  2. can a code with constructor and protoype be written using just object literals without using constructor and protoype.

  3. what is the signifiance of anonymous function.

A very simple example demonstrating their importance will also do.I am aware of what they are but I am not aware of what possible magic they can do.

HIRA THAKUR
  • 17,189
  • 14
  • 56
  • 87

1 Answers1

29

There is a (fundamental, in my opinion) difference between object literals and functions, the "private" variables. Since an object can't be instantiated(because it is already an instance of Object) it has no possibility to have its own (new) scope. It is a base concept of advanced JS programming. Having a new scope allows you to do almost everything(you can declare your own window, document or whatever you want except the JS keywords inside your own scope). Now, some simple examples:

Let's assume you want to create a large number of instances of the same object(using as few lines as possible):

function MyObj(i) {
    var privateCounter = "I am the instantiated object " + i + " .";
    this.counter = function() {
        return privateCounter;
    };
}

var MyObjList = [],
    ObjLitList = [];
for (var i = 0; i < 100; i++) {
    MyObjList.push(new MyObj(i));
    ObjLitList.push({counter: "I am the literal object number " + i + "."});
}

Now you have 200 objects that are almost, but not precisely, the same thing. You can extend them as you prefer, because functions are objects, but in the case of the function you cannot access the private variable directly. Let's see which are the advantages of a function:

  • It is treated like an Object
  • It has its own Prototype
  • It has private variables

And the Objects?

  • It is an Object
  • It doesn't have its own Prototype, but you can declare the functions and extend the object itself
  • It doesn't have private variables

Apart the private vars, they are not much different from each other.

Let's see what a function's prototype can do:

MyObj.prototype.setX = function(x) {
    this.x = x;
}

Using the prototype allows you to create an only instance of an anonymous function(which can be named too and then assigned) which will be shared across instances. How can you do the same thing with object literals?

function setX(x) {
    this.x = x;
}
var obj = {
    setX: setX
};

As you can see you have to create the object defining everytime a property which is setX. Otherwise, you can extend Object.prototype itself(but there is a long debate about extending the prototype of native JS objects).

So which is the best way? There is no one, it depends on what you have to do, what you need from your script, which of the two you feel more comfortable with.

I prefer writing my own functions and treat them like classes, because they are more readable and I am able to use "private" variables. I don't know anyone using literals instead of functions though.

As for the questions:

Which is the best preferred way of programming(object literals vs constructors vs prototype)

Answered.

can a code with constructor and protoype be written using just object literals without using constructor and protoype.

Yes, you can if you don't need private variables(and if the script isn't too big. Imagine jQuery written as an Object literal :D).

what is the signifiance of anonymous function.

Oh well, I can answer with an example:

//code
myNamedFunction();
//code
function myNamedFunction() {
    alert("I'm defined everywhere! :)");
}

This works and won't generate a TypeError.

myAnonymousFunction();
var myAnonymousFunction = function() {
    alert("I'm defined after this declaration :(");
}
myAnonymousFunction(); // works!

This will cause a Uncaught TypeError: undefined is not a function, because myAnonymousFunction is only a reference to the effective function(which is unnamed, so it is not callable from the script).

There are a lot of things to say about this argument, and a good point to start advanced programming is Javascript Garden. Other good readings are Basics of OOP in JS - NetTutsPlus, Working with Objects - MDN and OOP in JS - Phrogz

Hope this helps!

Sidenote: functions also have a good advantage since they can change their context(this) just with a function(call for example), while objects can't.

Community
  • 1
  • 1
Niccolò Campolungo
  • 11,824
  • 4
  • 32
  • 39
  • It is private and not accessible from the outside of the function – Niccolò Campolungo Jun 23 '13 at 14:12
  • MyObjList.push(new MyObj(i));--------------------1 ObjLitList.push({counter: "I am.......})----------2 what is the difference between 1 and 2. Is this instantiation just like constructor do using new keyword. – HIRA THAKUR Jun 23 '13 at 14:26
  • Yes, the first is instantiated using MyObj function, the second is istantiated via JS's compiler({} evaluates to new Object() and the setting of the properties). As I said, there is no true difference between the function(which is an Object itself) and an object literal, aside the private vars. Everything in JS in "istantiated"! If you do var n = 2 it is a Number! – Niccolò Campolungo Jun 23 '13 at 14:33
  • 1
    If I understood correctly, the TypeError generated in the anonymous function in the second example is due to the variable `myAnonymousFunction` has been declared and undefined at the top of the script, hence the `TypeError undefined is not a function`. Has to do with js `hoisting`. – snw Mar 08 '14 at 16:33
  • Yes, it is. But at the time I wrote the answer I didn't know yet so good about JS's hoisting, so I tried to justify it myself without any proof. The variable is hoisted at the top of the script, but has value undefined, which is not a function, hence the TypeError. In fact, if you try to call a function which is not even declared you get a ReferenceError, telling "x is not defined", which is a lot different from "undefined" :) thanks for pointing it out, hope to have been clear! – Niccolò Campolungo Mar 08 '14 at 17:58
  • one of the best answers I've ever read. It is such a wonderful practice to quote your references at the end thanks a lot. – Rishul Matta Jul 29 '14 at 05:29
  • Thanks @LightStyle. That cleared the confusion for me between object literals and constructor + prototype. The statement you made ({} evaluates to new Object()) makes a lot of things clear for me. – Sai Gudigundla Aug 05 '14 at 03:09
  • Thanks for putting this down. If I may suggest a correction for the `Uncaught TypeError` example from calling `myAnonymousFunction()`, the reason for this error is that only the variable _declaration_ is hoisted (e.g. `var a;`), and not the attribution (e.g. `a = 'foo';)`, meaning it is not even a reference to the function at that point. That's why you don't have a `ReferenceError`, which in that case would mean the variable was not _declared_ in the executing or nested scope(s). – gmsecrieru Jun 01 '16 at 19:38
  • This answer has made my life worth living again. Thanks Nico – Amin Mohamed Ajani Jun 30 '16 at 07:02