I've created the following jQuery OOP code
(function ($) {
example = {
method1 : function() {},
method2 : function() {}
};
})(jQuery);
I don't want to use init() and call some methods on document ready. Is there any way to execute/run the object in literal notation?? I used var example = new Object(); but I'm getting error, I just need all the methods associated to the objects to be running on ready.
This will do it :)
(function ($) {
// define some methods
var example = {
method1: function() { console.log(1); },
method2: function() { console.log(2); }
};
// run all methods in example
for (var m in example) {
if (example.hasOwnProperty(m) && typeof example[m] === "function") {
example[m]();
}
}
// => 1
// => 2
})(jQuery);
If you want to use new such as
var example = new Example();
// => "A"
// => "B"
You could do something like this
(function($) {
var Example = function() {
this.initializeA();
this.initializeB();
};
Example.prototype.initializeA = function() {
console.log('A');
}
Example.prototype.initializeB = function() {
console.log('B');
};
// init
new Example();
// => "A"
// => "B"
})(jQuery);
Perhaps this is what you're looking for?
(function ($) {
example = (function() {alert("some code")})();
//or
(function() {alert("some other code")})();
//or
alert("even more code");
})(jQuery);
Related
I have something similar to this:
var a = (function () {
return {
b: 1,
c: function () {
console.log(this.b);
}
};
})();
So,
a.c(); // = 1
But if I do
b = 2;
a.c.apply(this); // = 2
Is it possible to preserve the context of "this" inside "a.c()" without changing (too much) the structure of "a" object? I don't have the control of the function's call, so I'd need a workaround to deal with this inside the object itself.
UPDATE:
To be more specific, this is the structure of my files:
Structure 1 (singleton like pattern):
var a = (function () {
var _instance;
function init() {
return {
b: 1,
c: function () {
console.log(this.b);
}
};
}
return {
getInstance: function () {
if (_instance === undefined) {
_instance = init();
}
return _instance;
}
}
})();
Structure 2:
var b = {
c: 1,
d: function () {
console.log(this.c);
}
};
SOLUTION:
I have implemented a solution based on Mahout's answer, spliting the return statement inside init(), so it remains safe for the object context (and the instance) under any situation.
For singleton pattern:
var a = (function () {
var _instance,
self;
function init() {
return self = {
b: 1,
c: function () {
console.log(self.b);
}
};
}
return {
getInstance: function () {
if (_instance === undefined) {
_instance = init();
}
return _instance;
}
};
})();
For object literal:
var b = (function () {
var self;
return self = {
c: 1,
d: function () {
console.log(self.c);
}
};
})();
So
a.getInstance().c(); // 1
a.getInstance().c.apply(this); // 1
setTimeout(a.getInstance().c, 1); // 1
$.ajax({ complete: a.getInstance().c }); // 1
You can slightly change the way you are returning the object from the anonymous function:
var a = (function () {
var result = {};
result.b = 2;
result.c = function() {
console.log(result.b);
};
return result;
})();
This should have the same effect, however it does remove the use of this.
If you can't afford to change the structure of a this much, then alternately you can (much) more dangerously use:
a.c.apply = function() { // Stops the apply function working on a.c by overriding it
return a.c();
}
If you choose this though you must be wary that anytime a.c.apply is used it will no longer work 'as expected' - it will fix the issue presented here though.
I made this pen to illustrate the differences,I hope it helps:
http://codepen.io/dieggger/pen/BNgjBa?editors=001
var a = (function () {
return { b: 1,
c: function () {
console.log(this.b);
}
};
})();
a.c(); //prints 1
b = 2; // global variable "b" which is being hoisted BTW
// The following will act like this:
//it throws "cannot read property 'apply' from undefined"
//though it prints "1" since the first part invokes the "c" function
//inside of the"a" module which has the console.log
a.c().apply(this);
//In this case "this" is the window object which has the variable "b"
a.c.apply(this); // it'll print 2
You can do this:
var a = (function ()
{
return {
b: 1,
c: function ()
{
console.log(this.b);
}
}
})();
var decorator = function() { return a; };
var b = 2;
decorator.call(this).c(); // => 1
Basically it looks like you want to bind the IIFE, and not the object that it returns, to the outside scope, so that the nested returned object preserves the value of the interior b.
this is my code:
window.myApp= window.myApp|| {};
myApp.jira = (function () {
var getId = function () {
return ...;
}
var init = function() {
var id = myApp.jira.getId();
}
})();
$(document).ready(function () {
myApp.jira.init(); // here jira is null and getting undefined
});
when the page is loaded it says jira is undefined.
Try this:
window.myApp= window.myApp|| {};
// Function here is being immediately invoked. No "return" statement
// in your code is equivalent to "return undefined;".
myApp.jira = (function () {
var getId = function () {
return ...;
}
var init = function() {
var id = myApp.jira.getId();
// Bonus note: you can simplify this:
// var id = getId();
}
// If we return an object with functions we want
// to expose (to be public), it'll work,
return {
init: init,
getId: getId
};
})(); // <-- here you'll invoking this function, so you need return.
$(document).ready(function () {
// Without 'return' above, myApp.jira evaluated to undefined.
myApp.jira.init();
});
Working DEMO
Or you can use object literal pattern instead:
var myApp = {};
myApp.jira = {
getId: function () {
return ...;
},
init: function() {
var id = this.getId();
}
};
Where can I accommodate ready function in the name space?
var yourNamespace = yourNamespace || {
foo: function()
{
},
bar: function()
{
}
};
...
yourNamespace.foo();
ready function:
$(function(){
...
});
Here's how I do it:
var MyNamespace = (function(publicAPI) {
var foo = 'I am a private field';
publicAPI.alertFoo = function() {
alert(foo);
};
// DOM ready
$(function() {
$('.test-link').click(function() {
publicAPI.alertFoo();
});
});
return publicAPI;
})(MyNamespace || {});
To call the alertFoo method you would use MyNamespace.alertFoo(); This is a variation of the module pattern. The DOM ready section is used for binding to events.
Let's say I have the namespace,
var Namespace = {
A : function() {
alert('Hello!');
},
B : function() {
// Call A() from here, do other stuff
}
}
In this namespace, I intend for A to be a helper function to B. That is to say, A() will never be called outside the namespace. It will only be called by the functions within the namespace.
What's the best way to address the issue of a local/helper function within a namespace? The way I see it there are two possibilities:
// Method #1
var Namespace = {
A: function() {
alert('Method #1');
},
B : function() {
Namespace.A();
}
}
Namespace.B();
// Method #2
function Namespace2() {
var A = function() {
alert('Method #2');
};
this.B = function() {
A();
}
}
var ns2 = new Namespace2();
ns2.B();
In the first method, it is ugly and awkard to type Namespace.A() (repeatedly) in every function within the namespace. This leads me to prefer Method #2. But I was curious what was the best practice here.
I recommend placing the "namespace" inside a function scope. Everything not explicitly public will be naturally private:
var Namespace = (function() {
var self = {};
// Private
var A = function() {
...
};
// Public
self.B = function() {
A();
}
return self;
}());
Namespace.B(); // Works
Namespace.A(); // Doesn't work
You can call it using this statement
this.A();
Well you can event use a third option where the Namespace is created in it's own scope:
var Namespace = (function(){
var A = function() {
alert('scoped method');
};
function Namespace() {
var A1 = function() {
alert('Namespace "private" method');
};
Namespace.prototype.B1 = function(){
A(); //will run
A1(); //will run with no errors
};
};
Namespace.prototype.B = function(){
A(); //will run
A1(); //ERROR!
};
return Namespace;
})();
If you only intend to use A inside B, why not define it inside B?
var Namespace = {
B: function() {
var A = function() {
...
}
A();
}
};
Namespace.B();
var Namespace = {
A : function() {
alert('Hello!');
},
B : function() {
Namespace.A();
},
}
note the Semi-colon at the end
I have the following code
var PROMO = PROMO || {};
PROMO.Base = (function () {
var _self = this;
var Init = function () {
WireEvents();
};
var WireEvents = function () {
//wire up events
};
} ());
In the same file I have the code to call the above function
I am trying to get to an end point where I can use the following code
$(document).ready(function () {
PROMO.Base.Init();
});
this gives the error
Cannot call method 'Init' of undefined
Now I know there are many ways to write javascript, but in this case I want to be able to call my functions, or least the Init method in the way shown above.
var PROMO = PROMO || {};
PROMO.Base = (function () {
var _self = this;
var Init = function () {
WireEvents();
};
var WireEvents = function () {
//wire up events
};
var reveal = {
Init: Init
};
return reveal;
} ());
You need to return the public facing functions. See updated code.
Working fiddle with both patterns, using IIFE and direct attribution.
Using var makes the definition private and your function is returning nothing. Use this:
PROMO.Base = {
Init: function() {
},
WireEvents: function() {
};
};
You are wrapping the definition with an IIFE(Immediately Executed Function Expression). So your PROMO.Base object will be assigned the value of that (function(){//blabla})(); returns. But your function doesn't have a return statement. By default it will return undefined.
Which is way your PROMO.Base will be undefined and you get this:
Cannot call method 'Init' of undefined
If you really want that IIFE:
var PROMO = PROMO || {};
// NEVER use _self = this inside static functions, it's very dangerous.
// Can also be very misleading, since the this object doesn't point to the same reference.
// It can be easily changed with Function.prototype.call and Function.prototype.apply
PROMO.Base = (function () {
_PROMO = {
Init : function () {
document.body.innerHTML += "itworks";
},
WireEvents : function () {
//wire up events
}
}
return _PROMO;
} ());
PROMO.Base.Init();
Update
The better and easier pattern is to simply assign the functions to PROMO.Base. Dully note you should not capitalize static functions, but only constructors. So if something is not meant to be instantiated, don't call it Init, it should be init. That is the convention.
var PROMO = {};
PROMO.Base = {};
PROMO.Base.init = function() {
console.log("this works");
};
PROMO.Base.wireEvents = function() {
console.log("this is a static function too");
};
You can attach it to the window object like ...
window.PROMO = (function($, _){
// this will access PROMO.Base
PROMO.Base = {
// inner functions here
Init:{}
};
})(jQuery, _);
Then load it as you do.
Or if you depend from jQuery
(function($){
var PROMO = {
// inner functions
Init: function(){},
WireEvents: function(){}
};
$.PROMO = PROMO;
})(jQuery);
On DOM ready
jQuery(function ($) {
var promo = $.PROMO || undefined;
promo.Base.Init();
});