I have been reading a few different Javascript authors and each has their preferred way to declare properties on objects. None of the authors really explains the difference
In JavaScript you can declare "Objects" via several ways. The most easy way is:
var myObject = {}
from here on, adding methods or attributes is very easy as well:
myObject.myFirstMethod = function(){};
myObject.myFirstAttr = true;
myObject.mySecondAttr = "hello world!";
in this case, you would add those functions and attributes to your "myObject" Object. But there is a better and much cleaner way to do such stuff:
var myObject = function();
myObject.prototype.method1 = function(){};
myObject.prototype.method2 = functiion(){};
myObject.prototype.attr1 = true;
myObject.prototype.attr2 = "hello world!";
myObject.prototype.setAttr1 = function(value){
this.attr1 = value;
}
myObject.prototype.setAttr2 = function(value){
this.attr2 = value;
}
if you declared your Object this way, you can use
var myObjectInstance = new myObject();
this Object now has got every methods and attributes which you had defined in your prototype. more about prototypes:
http://www.w3schools.com/js/js_object_prototypes.asp
edit:
note that "this" in JavaScript means the "element", what called the actual method and NOT the object itself in any case...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
tl;dr - See conclusion
Declaring objects in javascript can be done many different ways, and from my point of view it all depends on how complex your project is.
The examples you proposed would be ways to declare variables within a complex project. You could even say for project maintainability and code quality the examples you proposed can be very interesting.
Your first example you proposed was this function.
var One = function(){
var self = this;
self.foo = function(){};
return self;
}
Suppose we don't create an instance of One
(not using new
) This function has two objectives.
foo function
to its parents context (usually window object = globally)foo function
You could say you're killing two birds with one stone. While doing two things at once can be interesting, in the end it could really become a context
problem.
Context
is pretty much asking yourself, what does this
refer to? Non instantiated functions inherit the parents context
which is fine if none of those parents are instantiated themselves. If this is the case (meaning this
!= window object) and your primary goal was to attach foo
globally well it just won't work.
If you call this function with new
, this
will be different. this
will refer to an instance of One
. This is a lot more logical way.
In the end you could say that an instance of One will feel almost
like an object.
I say almost mainly because what is the difference if One was:
var One_object = {
foo: function(){}
}
Well there isn't really, except you'll be more flexible with an object rather than an instance
of a function.
//This will not work.
var a = new One();
a.titi = function(){
alert('titi');
}
//This will work
One_object.titi = function(){
alert('titi');
}
The only way that One
as an instance can become interesting is if you declare multiple instances. Performance wise and memory wise it'll be more interesting.
var One = function(foo){
//auto instantiate it's self
if(!(this instanceof One)){
return new One(foo);
}
this.foo = foo || function(){};
}
Creating multiple instances of One with the same function probably defeats the purpose, so here is an example of how you could improve One
.
var a = One(function(){
alert('instance one');
});
var b = One(function(){
alert('instance two');
});
var two = function() {
foo: function() {}l
};
Is actually wrong as I'm sure you've noticed from the comments. It should be instead:
var two = {
foo: function() {}
};
Where two
is in fact an object
and not a function
.
This way of declaring variables/functions ensures that you are not overriding on a global scope any other function named "foo"
.
This can be very useful when you have a lot of js and you are declaring a lot of variables.
In this case, to access foo
you need to simply call two.foo();
This is honestly my preferred way of declaring variables.
With this in mind, here is an example:
var options = {
foo: function(){
console.log('This is foo');
},
toto: function(){
console.log('This is titi');
}
};
var example = function(options){
options.foo();
options.toto();
}
example(options);
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
A good standard when writing code is to keep the code readable. While this may work, it's not good practice. The main issue with writing Javascript is that it can easily become unreadable.. And in this case it feels barbaric (personal opinion).
As you've probably noticed example two is my preferred way (and to many others I know) in declaring Objects for the following reasons:
Feel free to point out on anything I've missed.