Very simple question, not sure if there are any differences in these ways of creating a javascript "module". I'm hoping somebody can clarify it for me.
A)
var foo = function() {
var bar = function() {
console.log('test');
};
return {
bar: bar
};
};
B)
var foo = function() {
function bar() {
console.log('test');
};
return {
bar: bar
};
};
C)
var foo = function() {
this.bar = function() {
console.log('test');
};
return {
bar: this.bar
};
};
A and B are essentially the same, though there is a very minor difference between A and B due to function/variable hoisting, theoretically you could write code which would work in B but break in A, but practically speaking you'd have to really write weird code to do so.
C will work, but is conceptually wrong. The point of using this.funcName in a function is as a constructor (creating lots of objects using new Thing(). If you aren't using the function as a constructor you shouldn't be using that style as someone scanning the code may mistake the function as a constructor instead of its actual purpose which is a module.
At first, you forgot to execute the function expression: the module pattern is an IEFE. You just create a function.
Your last example is nonsense, it looks like a constructor function when assigning properties to this - and when executed as a IEFE it breaks (and using it with new has undesired effects; an when returning an object it's useless).
For the difference between the first and the second snippet see var functionName = function() {} vs function functionName() {}. In context of the module pattern, the function declaration is recommended.
//Javascript Module Pattern
var person = (function() {
var cname = 'CheapFlight';
return {
name: "Santosh Thakur",
getAge: function() {
return cname;
},
growOlder: function() {
return cname + " Updated";
}
};
}());
person.cname = "New Company"
console.log(person.cname);
console.log(person.name);
console.log(person.getAge());
console.log(person.growOlder());
prefix var before a function makes it a "class"-ish, this means you can make many versions of it. This goes for A
For example:
var hi = function()
{
var bye = function()
{
alert("bye");
}
bye(); // this will call bye
var something = new bye(); // this will create a new instance of bye();
}
var something = new hi();
something();
B means you can only call bar, not make a new instance of it inside the function.
C is the same as bar because of its scope
Class-ish:
var Dog = function( hair, type )
{
this.hair = hair;
this.type = type;
}
var fred = new Dog( "long", "Dalmation" );
alert( fred.hair );
var dave = new Dog( "short", "Poodle" );
alert( dave.type);
This is a class ^
Related
For some time now, I've been using the design pattern of objectOne, shown below. I cannot remember where I picked it up. I tried to find it but couldn't. Perhaps its some hybrid of things I read about. Today I discovered that it is very flawed, since this is resolving to the window object, making all public methods global. I was under the impression that when this is used within a function, it would refer to the function itself, as opposed to the global window object. I guess this is not the case? Could someone explain something that I'm missing or point me to a resource that explains it? I'm also interested in either fixing this pattern or finding a similar one that doesn't have this problem with global method names. I suppose if I would use a variable other than this, perhaps fn, and i return that, then it would fix things. Thanks in advance for any help with this question, sorry its sort of vague.
JS Fiddle:
http://jsfiddle.net/nLL8y/3/
myapp = {};
myapp.objectOne = function() {
var that = this,
p = {};
this.public = function() {
console.log(this);
};
p.private = function() {};
return this;
}();
myapp.objectTwo = {
public: function() {
console.log(this);
},
notPrivate: function() {}
};
myapp.objectThree = function() {
var fn = {},
p = {};
fn.public = function() {
console.log(this);
};
p.private = function() {};
return fn;
}();
//creates global functions
myapp.objectOne.public();
//doesn't allow private
myapp.objectTwo.public();
//seems to work
myapp.objectThree.public();
myapp is used as a namespace in your example. objectOne and objectTwo are constructors so they should start with capital letter. But your biggest problem is using methods directly as opposed to creating objects:
var myapp = {};
myapp.ObjectOne = function() {
this.public = function() {
console.log(this);
};
var private = function() {};
};
myapp.ObjectTwo = function() {
this.public = function() {
console.log(this);
},
this.notPrivate = function() {}
};
var o1 = new myapp.ObjectOne();
o1.public();
var o2 = new myapp.ObjectTwo();
o2.public();
I've been using the below, I've seen other code using function() { } and then using the this keyword, what is the difference here, have I actually instantiated an object below?
var MyObj = {
propertyOne: 'a',
Method: (function() {
function MyFuncOne() {}
function MyFuncTwo() {}
return {
MyFuncOne: MyFuncOne,
MyFuncTwo: MyFuncTwo
}
})()
}
Yes, you've instantiated a "singleton" object with two methods.
I believe the outer curly braces are unnecessary, and you could just write:
var MyObj =
(function() {
function MyFuncOne() {}
function MyFuncTwo() {}
return {
MyFuncOne: MyFuncOne,
MyFuncTwo: MyFuncTwo
};
})();
Another way to do it is:
var MyObj =
(function() {
var obj = {};
obj.MyFuncOne = function() {};
obj.MyFuncTwo = function() {};
return obj;
})();
Wrapping your JS in (function() { /* code here */ })() is good practice for preventing variables leaking into global scope. In this case, you're using it to assemble an object.
The only reason I can think of for doing something like this is if you wanted to have some private variables that were shared between the two functions (after changing it to make it legal javascript):
var MyObj = (function() {
var x,y,z; // these will be accessible only to
// the MyFuncOne and MyFuncTwo functions
function MyFuncOneA() {}
function MyFuncTwoA() {}
return {
MyFuncOne: MyFuncOneA,
MyFuncTwo: MyFuncTwoA
}
})();
I had to change your syntax to even make it work because as you had it myObj = {{...}} which isn't very useful and may have not even been valid.
Other than this private, but shared variables notion, it's just extra (and confusing) syntax for declaring two methods on an object which there are much clearer ways to do.
If you weren't using the private variables, then the above example is functionally the same as this much simpler syntax which makes a lot more sense to me:
var MyObj = {
MyFuncOne: function() {},
MyFuncTwo: function() {}
};
Using a function with the this keyword allows you to do some more things than are possible (or, at least, easy) with an object literal (which is what your anonymous function above returns). Most commonly, creating "types".
function Animal () { }
Animal.prototype.speak = function () {
return "";
};
var dog = new Animal();
dog instanceof Animal; // returns true
This also makes inheritance easier:
function Feline () { }
Feline.prototype = new Animal;
Feline.prototype.speak = function () {
return "meow";
};
function Lion () { }
Lion.prototype = new Feline;
Lion.prototype.speak = function () {
return "roar";
};
function Cat () { }
Cat.prototype = new Feline;
var leo = new Lion();
var baxter = new Cat();
leo.speak(); // returns "roar"
baxter.speak(); // returns "meow" - from prototype chain
leo instanceof Feline; // returns true
leo instanceof Animal; // returns true
leo instanceof Cat; // returns false
Demo: http://jsfiddle.net/hEnJf/
Let us say I have the following:
var foo = (function(){
var bar = 0;
return {
getBar: function(){
return bar;
},
addOne: function(){
bar++;
},
addRandom: function(rand){
bar += rand;
}
}
})();
And I have the following:
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
}
};
Is the only difference in executing the functions a new?
alert(foo.getBar()); //0
foo.addOne();
foo.addRandom(32);
alert(foo.getBar()); //33
var foo2_obj = new foo2;
alert(foo2_obj.getBar());//0
foo2_obj.addOne();
foo2_obj.addRandom(32);
alert(foo2_obj.getBar());//33
They both out put the exact same thing.
So what is the difference in the long run?
What can one do that the other cannot?
Fiddle Demo of the above: http://jsfiddle.net/maniator/YtBpe/
In the first one you can only create the object once, while with the second one you can create as many objects as you like. I.E. the first one is effectively a singleton.
Note that closures are not ok for the second one. Every time you instantiate it you are creating the functions all over again and waste a ton of memory. The prototype object is intended to counter this, where you can create the functions once outside a function scope and no accidental closures are created.
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
Then:
var a = new foo2, b = new foo2, c = new foo2;
Creates three instances which have their own _bar but share the same functionality.
jsperf
You can "compare" all of this to PHP, some of the code won't even run but it's "equivalent" in principle:
var foo = (function(){
var bar = 0;
return {
getBar: function(){
return bar;
},
addOne: function(){
bar++;
},
addRandom: function(rand){
bar += rand;
}
}
})();
is roughly "equivalent" to this in PHP:
$foo = new stdClass;
$foo->bar = 0;
$foo->getBar = function(){
return $this->bar;
};
$foo->addOne = function(){
$this->bar++;
}
$foo->addRandom = function($rand){
$this->bar += $rand;
}
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
}
};
Is roughly "equivalent" to this in PHP:
Class foo2 {
public function __construct(){
$bar = 0;
$this->getBar = function(){
return $bar;
};
$this->addOne = function(){
$bar++;
};
$this->addRandom = function($rand){
$bar += rand;
};
}
}
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
Is roughly "equivalent" to this in PHP:
Class foo2 {
public $_bar;
public function __construct(){
$this->_bar = 0;
}
public function getBar(){
return $this->_bar;
}
public function addOne(){
$this->_bar++
}
public function addRandom($rand){
$this->_bar += $rand;
}
}
...and is the only one that is close to OOP in the three above examples
The only difference is that foo will be a generic Object, whereas foo2_obj will identify as a foo2 when checking its type (i.e. foo2_obj.constructor == foo2 will be true, while the equivalent on foo is foo.constructor == Object).
Of course, there's an important distinction between foo and foo2 - foo is an object, while foo2 is a function (intended for use as a constructor). Thus, it is trivial to make as many instances of foo2 (of which foo2_obj is one), while the idea of creating "instances" of foo doesn't really make sense - the best you could do are copies (which is more difficult than calling a constructor).
Due to the copying/creating instances distinction, the second approach allows for real OO programming with prototype chains, while the first makes such things much more difficult (and ill-advised).
[1]first,but not important:efficiency
function Foo1() {
var bar = 0;
return {
getBar: function () {
return bar;
}
}
}
var o = Foo1();
o.getBar();
function Foo2() {
var bar = 0;
this.getBar = function () {
return bar;
}
}
var o = new Foo2();
o.getBar();
which is the faster?,look object-literal-vs-new-operate
[2]program pattern:the former has no program pattern,but the latter will benefit form prototypal inheritance.if now we want to add a method named "logBar",
former:
1:extend every Foo1 instance:
o.logBar = function () {
console.log(this.getBar());
}
o.logBar();
bad way!
2:find where Foo1 defined and add:
function Foo1() {
var bar = 0;
return {
getBar: function () {
return bar;
},
logBar:function () {
console.log(this.getBar());
}
}
}
var o = Foo1();
o.logBar = o.logBar();
would you want to go back to do this when you want to add more method ervey time?
latter:
Foo2.prototype.logBar = function () {
console.log(this.getBar());
}
var o = Foo2();
o.logBar = o.logBar();
this would be work fine.
[3] back to efficiency:
in Foo1's way,it product logBar function instance ervey time when a Foo1 instance created.object-literal-vs-new-operate
I think in my personal view of this two types
1- Singleton
2- Object
Let's we say we have one page having their javascript using Object (Second), and
having many utils using singletons (First), and works fine.
But one day we need a new page that call the first page via AJAX, this new page have their javascript using Object (Second) and have the same utils using singleton, but we add some new functions in the utils singletons.
Turns out, the utils singletons in the new page are overriden for the loaded utils singletons in the first page, So when the new page execute some of those new function doesn't exist, generating errors ...
I think this is my point, the singletons are overriden when you have this scenario, and find erros in cases like this are hard.. hard..., diferent from a object that have unique instances
Cheers.
The main difference is actually that foo is an object, whereas foo2 is a function.
That means that you'll not be able to create another object like foo that is not actually foo itself, except if you copy/paste its code.
On the other hand, you can create another foo2 object and manipulate it while using foo2_obj for another purpose.
To make short, foo is an instance while foo2 can bee seen as a class (even if it's just a function constructing an object).
It depends on what you want to do in your program, but I'd surely recommend to use the 2nd form which is allowing to reuse your code by creating other instances.
foo and foo2_obj They are the same. In both cases you have a function that creates a new object, references a variable in closure scope and returns that object.
You have 4 things
anonymous function that is a factory for "foos"
object foo created from anonymous factory
foo2 which is a name factory for "foo2_objs"
object foo2_obj created from foo2 factory
The exact difference between using new and returning function literals from a function is neglible if you don't touch <Function>.prototype
You probably want to compare
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
};
};
To
var Foo = {
addOne: function () { this.bar++; },
addRandom: function (x) { this.bar+=x; }
};
var foo3 = function () {
return Object.create(Foo, { bar: { value: 0 } });
}
foo3 uses prototypical OO. this means you don't have to recreate those functions all the time.
In simple terms if you are creating 10 instances of foo and foo2, the getBar function of foo will exists 10 times in memory and that of foo2 will be only once.
Also, modern browsers like chrome with V8 compiler, it compiles the js to machine code... in that case foo2 will get translated to a native class object and its like a 20 times faster (when you create say 1000 instances in a loop)
I normally uses the simple object method when there is only once instance of that class/module is needed. The structure that I follow is,
var myInstance = function(){
var self = {};
self.bar = null;
self.gerBar = function(){
return self.bar
}
return self;
}();
this is quite similar to the foo approach, but I find this structure more handy.
One other difference (in practical use) that i normally encounter is when I have callback functions or timeouts inside the class,
var foo2 = function(){
this.doSomething = function(){
var temp = this;
$.someAsyncCall(function(){
// 'this' in current scope is the inline function itself, not the class instance
// so have to store the instance ref in a local var in outer scope and then use that to get the class instance
temp.callAfterAsyncCall();
});
};
this.callAfterAsyncCall = function(){
};
};
as you can see the local temp variable is not pretty when you have a lot these cases.
where in the other approach, you always the the self reference everywhere inside the module scope,
var myInstance = function(){
var self = {};
self.doSomething = function(){
$.someAsyncCall(function(){
self.callAfterAsyncCall();
});
}
self.callAfterAsyncCall = function(){
};
return self;
}();
I not sure if its important for you, but just thought worth mentioning.
I'm fairly certain this isn't possible, but wanted to see if anyone had some ingenious ideas as to how to make it possible.
I want the following code to work:
var x = new foo();
x.a.getThis() === x; // true
In other words, I want x.a.getThis to have a reference to this being x in this case. Make sense?
In order to get this to work one level deep is simple:
function foo(){}
foo.prototype.getThis = function(){ return this; }
var x = new foo();
x.getThis() === x; // true
One thing, I want this to work as a prototype, no "cheating" by manually binding to this:
function foo(){
this.a = {
getThis : (function(){ return this; }).bind(this)
};
}
Although the above is a perfect functional example of what I'm trying to achieve, I just don't want all the extra functions for each instance :)
FYI, the actual use case here is that I'm creating classes to represent Cassandra objects in node and I want to be able to reference a super-column --> column-family --> column via foo.a.b and keep a reference to foo in the deep function.
You can't do this without a forced bind of some kind. You say you don't want to "cheat" but this breaks the standard rules about what this is, so you have to cheat. But JS lets you cheat, so it's all good.
BTW, for what it's worth coffee script makes this so trivial.
foo = ->
#a = getThis: => this
The fat arrow => preserves the context of this for from the scope it was called in. This allows you to easily forward the context to another level.
That code gets compiled to this JS:
var foo;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
foo = function() {
return this.a = {
getThis: __bind(function() {
return this;
}, this)
};
};
Which basically just does what you say you do not want to do.
Or if the value doesn't have to this specifically, you can set the "owner" in the child object.
var A = function(owner) {
this.owner = owner;
};
A.prototype.getThis = function() {
return this.owner;
};
var Foo = function() {
this.a = new A(this);
};
var foo = new Foo();
if (foo.a.getThis() === foo) {
alert('Happy dance');
} else {
window.location = 'https://commons.lbl.gov/download/attachments/73468687/sadpanda.png';
}
http://jsfiddle.net/4GQPa/
And the coffee script version of that because I am a passionate and unreasonable zealot for it:
class A
constructor: (#owner) ->
getThis: -> #owner
class Foo
constructor: -> #a = new A(this)
foo = new Foo()
if foo.a.getThis() is foo
alert 'Happy Dance'
else
window.location = 'https://commons.lbl.gov/download/attachments/73468687/sadpanda.png'
Impossible to do reliably without binding the value at the start since the value of a function's this is set by the call. You can't know beforehand how it will be called, or which functions need a special or restricted call to "preserve" the this -> this relationship.
The function or caller's this may be any object, there may not be a this -> this at all. Consider:
var x = {
a : {
b: function() {return this;}
}
}
When you call x.a.b(), then b's this is a. But if you do:
var c = x.a.b;
c(); // *this* is the global object
or
x.a.b.call(someOtherObject);
What is the value of this -> this in these cases?
Answering my own question because someone else may find it useful. Not sure if I'll end up going with this or Squeegy's solution. The functions are only ever defined once and then the containing object is cloned and has parent = this injected into it:
function foo(){
var self = this, nest = this.__nestedObjects__ || [];
nest.forEach(function(prop){
self[prop] = extend({ parent : self }, self[prop]);
});
}
// bound like this so that they're immutable
Object.defineProperties(foo.prototype, {
bar : {
enumerable : true,
value : {
foobar : function(){
return this.parent;
},
foo : function(){},
bar : function(){}
}
},
__nestedObjects__ : { value : ['bar'] }
});
var fooInst = new foo();
console.log(fooInst.bar.foobar() == fooInst);
or based on Squeegy's solution:
function foo(){
for(var cls in this.__inherit__){
if(!this.__inherit__.hasOwnProperty(cls)){ continue; }
this[cls] = new (this.__inherit__[cls])(this);
}
}
var clsA;
// bound like this so that they're immutable
Object.defineProperties(foo.prototype, {
__inherit__ : { value : {
bar : clsA = function(parent){
Object.defineProperty(this, '__parent__', { value : parent });
}
}
}
});
clsA.prototype = {
foobar : function(){
return this.__parent__;
}
};
var fooInst = new foo();
console.log(fooInst.bar.foobar() == fooInst);
My colleague has been using "new function()" with a lower case "f" to define new objects in JavaScript. It seems to work well in all major browsers and it also seems to be fairly effective at hiding private variables. Here's an example:
var someObj = new function () {
var inner = 'some value';
this.foo = 'blah';
this.get_inner = function () {
return inner;
};
this.set_inner = function (s) {
inner = s;
};
};
As soon as "this" is used, it becomes a public property of someObj. So someObj.foo, someObj.get_inner() and someObj.set_inner() are all available publicly. In addition, set_inner() and get_inner() are privileged methods, so they have access to "inner" through closures.
However, I haven't seen any reference to this technique anywhere. Even Douglas Crockford's JSLint complains about it:
weird construction. Delete 'new'
We're using this technique in production and it seems to be working well, but I'm a bit anxious about it because it's not documented anywhere. Does anyone know if this is a valid technique?
I've seen that technique before, it's valid, you are using a function expression as if it were a Constructor Function.
But IMHO, you can achieve the same with an auto-invoking function expression, I don't really see the point of using the new operator in that way:
var someObj = (function () {
var instance = {},
inner = 'some value';
instance.foo = 'blah';
instance.get_inner = function () {
return inner;
};
instance.set_inner = function (s) {
inner = s;
};
return instance;
})();
The purpose of the new operator is to create new object instances, setting up the [[Prototype]] internal property, you can see how this is made by the [Construct] internal property.
The above code will produce an equivalent result.
Your code is just similar to the less weird construct
function Foo () {
var inner = 'some value';
this.foo = 'blah';
...
};
var someObj = new Foo;
To clarify some aspects and make Douglas Crockford's JSLint not to complain about your code here are some examples of instantiation:
1. o = new Object(); // normal call of a constructor
2. o = new Object; // accepted call of a constructor
3. var someObj = new (function () {
var inner = 'some value';
this.foo = 'blah';
this.get_inner = function () {
return inner;
};
this.set_inner = function (s) {
inner = s;
};
})(); // normal call of a constructor
4. var someObj = new (function () {
var inner = 'some value';
this.foo = 'blah';
this.get_inner = function () {
return inner;
};
this.set_inner = function (s) {
inner = s;
};
}); // accepted call of a constructor
In example 3. expression in (...) as value is a function/constructor. It looks like this:
new (function (){...})(). So if we omit ending brackets as in example 2, the expression is still a valid constructor call and looks like example 4.
Douglas Crockford's JSLint "thinks" you wanted to assign the function to someObj, not its instance. And after all it's just an warning, not an error.