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.
Related
I have an Javascript object following the Module Pattern
var foo = (function() {
var obj = (function() {
var $button = $('#myButton');
var init = function() {
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();
If I call foo.obj.init(), the button should be hidden, and this does not occur.
I saw different questions here about the assignment of an element to a variable, but I think that the problem is with the object. Can't I access a private variable from a public method?
From my comment:
Do it as part of init... you can just declare the var in order to isolate the scope, and then modify it to actually set the button as part of init
Example:
var foo = (function() {
var obj = (function() {
var $button; //$('#myButton');
var init = function() {
if (typeof $button === 'undefined') {
// i would probably make the selector an argument to `init`
// if i were you.
$button = $('#myButton');
}
$button.hide();
};
return {
init: init
};
})();
return { obj: obj };
})();
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'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);
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();
});
I've got a simple question about accessing variables in jQuery. Is there are way to access the variable (wrap) when I call the read function on click of 'a'.
(function() {
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();
There are a few ways to accomplish this. Perhaps the easiest is to change the scope of the 'wrap' variable. Currently, since it's declared with a var inside the init function, it's scoped to the init function and not available outside of init directly. So, you can declare the 'wrap' outside the init (it could be a property of the 'Example' object):
var Example= {
wrap: 'hello world',
init: function() {
var self = this;
$('a').click(function(){
self.read();
});
},
read: function() {
console.log(this.wrap);
}
};
Example.init();
This makes 'wrap' scoped to 'Example' and available as a property of 'Example' throughout any function defined within 'Example'.
(Edit: had to tweak this a bit to properly handle the closure.)
(function() {
var wrap;
var Example= {
init: function() {
wrap = 'hello world';
$('a').on('click', this.read);
...
Because functions have access to all variables visible from their definition scope.
(function() {
var Example= {
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(this.wrap)
}
};
Example.init();
})();
try this: (Fiddle: http://jsfiddle.net/jRJFQ/3/)
(function(){
var Example= {
wrap:null,
init: function() {
this.wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(Example.wrap)
}
};
Example.init();
})();
If you consider using the revealing module pattern you can define which variables are private and which are public like this:
var Example = (function(){
var wrap = 'hello world',
init = function(){
...
},
read = function(){
... // You can use `wrap` here
};
return { // Return public variables and methods
init: init,
read: read
};
})();
Example.init();
yup this should do it:
(function() {
var wrap;
var Example= {
init: function() {
var wrap = 'hello world';
$('a').on('click', this.read);
},
read: function() {
console.log(wrap)
}
};
Example.init();
})();