Should I be using object literals or constructor functions?
If you don't have behaviour associated with an object (i.e. if the object is just a container for data/state), I would use an object literal.
var data = {
foo: 42,
bar: 43
};
Apply the KISS principle. If you don't need anything beyond a simple container of data, go with a simple literal.
If you want to add behaviour to your object, you can go with a constructor and add methods to the object during construction or give your class a prototype.
function MyData(foo, bar) {
this.foo = foo;
this.bar = bar;
this.verify = function () {
return this.foo === this.bar;
};
}
// or:
MyData.prototype.verify = function () {
return this.foo === this.bar;
};
A class like this also acts like a schema for your data object: You now have some sort of contract (through the constructor) what properties the object initializes/contains. A free literal is just an amorphous blob of data.
You might as well have an external verify
function that acts on a plain old data object:
var data = {
foo: 42,
bar: 43
};
function verify(data) {
return data.foo === data.bar;
}
However, this is not favorable with regards to encapsulation: Ideally, all the data + behaviour associated with an entity should live together.
Javascript Constructor vs Object Literal Confusion
Consider:
function Person(name) { /* either of your approaches */}
Person.prototype.getName = function() {
return this.name;
}
Method 1 will work as expected, method 2 will not, if you call:
new Person('Bob').getName ()
Object literal vs constructor+prototype
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 Object
s?
- 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.
Javascript Object : Literal Vs Constructor
When defining something literally, the object is being built directly in the code. It doesn't exist yet until it is complete. At that point, this
would have no meaning (not that there is any need for it either).
To understand this in the object creation function, first realize that this
is special in JavaScript. Whenever you call a function, you can pass anything you want to be this
. In general, things like event handlers will pass the event-causing DOM object to be passed as this
. In your code, you do this as: MyFunction.call(whatever_needs_to_be_this[, param0, param1]);
. When you use the new operator, such as var mything = new SomeThing();
, JavaScript is essentially doing something like:
var mything = {};
SomeThing.call(mything);
this
in this case is going to be mything
in your function.
Literal notation VS. constructor to create objects in JavaScript
Object literals are usually the way to go. They only need to be parsed when loading the script, which can introduce various optimizations by the scripting engine.
Constructors need to be executed. That means they will be slower, but you can easily add some validation code etc. to them, and they allow the construction of complex objects with public, privileged methods and private "attributes" hidden in the constructors scope. Also, they of course construct objects that share a prototype, which you might find useful.
Related Topics
How to Create Dynamic Variable Names Inside a Loop
How to Convert Dd/Mm/Yyyy String into JavaScript Date Object
Named Capturing Groups in JavaScript Regex
Is JavaScript an Untyped Language
Are There Pointers in JavaScript
Update Style of a Component Onscroll in React.Js
How to Return a List of All the Image File Names from a Folder Using Only JavaScript
New Function()' with Lower Case "F" in JavaScript
How to Poll a Google Doc from an Add-On
How to Measure a Time Spent on a Page
Swap Rows with Columns (Transposition) of a Matrix in JavaScript
Converting a String to JSON Object
Why am I Getting a Referenceerror: Abortcontroller Is Not Defined in Discord.Js V13
How to Detect Window.Print() Finish
Getting Current Date and Time in JavaScript
How to Execute Shell Command in JavaScript