Javascript Module pattern. How to access globals inside the module - javascript

I have seen the following code
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
the properties can be accessed like MODULE.moduleProperty ...right?
But how to access globals privateVariable and privateMethod() inside the module(which are globals insode the module ...right?)

You can only access them from WITHIN the module code itself as such:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
alert('this is private!');
}
my.moduleProperty = 1;
my.moduleMethod = function () {
privateMethod();
return privateVariable;
};
return my;
}());
Doing this:
MODULE.moduleMethod();
Will call private method (and alert 'this is private!') and return the value of privateVariable.
There is no way to access privateVariable or privateMethod outside the MODULE scope.
var MODULE = (function() {
//...declare your module as above
}());
console.log(MODULE.privateVariable); //logs undefined
Hopefully that helps clear it up for you.

No, they are not global, they are local variables inside the anonymous function.
You can access them from any code within the function, but outside the function they are not directly accessible.

Related

Passing information between JavaScript methods

I have an object with two different sets of objects inside:
var myObj;
(function (myObj) {
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function myFunction2() {
}
myFunction2.prototype.something = function () {
var a = myFunction.getValue();
}
return myFunction2;
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
Every time I run myFunction2.something(), a is assigned: undefined.
How can I get the value from myFunction into myFunction2.something()?
There is quite a mixup of scopes and design patterns in your code. Having 2 functions named the same way on inside the other creates different scopes for that name depending on where you call them. This quickly gets out of control. Like in this part:
var myFunction = (function () { // this guy is named myFunction
function myFunction(){ // this guy is also named myFunction
this.myValue = "something"; // 'this' here most certainly refers to 'window', not myFunction. Unless you do a 'new myFunction()' a la prototype
}
myFunction.getValue = function () {
var _this = this;// same here
return _this.myValue;
}
return myFunction;// here you are returning a function, not an object with methods
})();
Also I noticed that you are handling some logic with prototypes and other with closures, this also is kinda confusing when someone else (or you in a couple of months) need to refactor this code.
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
You could go all prototypes or all closures. I prefer closures so here is what I would do.
var myObj;
(function (myObj) {
// in this closure, we create a scope and return only the public methods
var myFunction = (function () {
// define properties here
var myValue = 'default value';
// define your methods, here we return
// myValue declared on the parent scope
function getValue() {
return myValue;
}
// this acts as a constructor, it autoexecutes
(function init(){
myValue = "something";
})();
// return all the functions in this scope
// you want to expose
return {
getValue: getValue
};
})();
// we then put myFunction into myObj
// at this point myFunction is an object with a method called getValue()
myObj.myFunction = myFunction;
var myFunction2 = (function () {
function something() {
// once this guy is called, we get the value from the other 'class'
var a = myFunction.getValue();
alert(a);// voila!
}
(function myFunction2() {
// do your init stuff here
})();
return {
something: something
};
})();
myObj.myFunction2 = myFunction2;
})(myObj || (myObj = {}));
// at this point myObj is an object with 2 'classes', each 'class' has its own methods
// we can proceed and call the desired method
myObj.myFunction2.something();
Demo: http://jsfiddle.net/bzw9kse7/
I've stepped through your code and just noticed a couple small things you're doing wrong.
You appear to be misdefining myFunction slightly, because it's not going to have myValue as a member variable, just a temporary variable that quickly falls out of scope. (And because it becomes undefined, it gets assigned to a, which is then unassigned).
So, replace these lines:
var myFunction = (function () {
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
With this:
var myFunction = (function () {
var myFunction = {};
myFunction.myValue = "something";
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
return myFunction;
})();
EDIT Sorry, got this all wrong. It returns undefined because getValue is a static method of myFunction Object, not an instance method. That means that the this is not the same as in myFunction constructor.
Moreover you are not even attaching myValue to the this anywhere...
Edit 2 I added getMyValue to the myFunction prototype.
Try this:
....
var myFunction = (function () {
function myFunction(){
this.myValue = "something";
}
myFunction.prototype.getValue = function () {
return this.myValue;
}
// this creates the instance of the myFunction class.
return new myFunction();
})();
myObj.myFunction = myFunction;
...
// now you should be able to see the right result
var a = myFunction.getValue();
This is one of the craziest code I have ever seen, but the answer is this:
var a = myFunction.getValue(); is undefined because your 2nd definition of myFunction returns undefined, as in here:
function myFunction(){
var myValue = "something";
}
Your 2nd definition of myFunction actually replaces the 1st. See the comments below:
var myFunction = (function () {
// this definition replaces the one above
function myFunction(){
var myValue = "something";
}
myFunction.getValue = function () {
var _this = this;
return _this.myValue;
}
// which makes this return to not be taking in account when you are
// calling myFunction()
return myFunction;
})();

Access of function in jQuery scope

I want to build a function outside a jQuery scope:
(function($) {
function MyObject() {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();
But function MyObject is not accessible :
ReferenceError: MyObject is not defined
However, if i build my function in the scope, it's working:
(function($) {
function MyObject() {
console.log('foo');
};
var $my_object = new MyObject();
}(jQuery));
foo
How access to MyObject outside the scope ?
I would probably not recommend it but you can basically do what you want by returning the functions as part of an object and assigning the IIFE to a variable like this
var library = (function ($) {
var exports = {};
var private = 'see you cant get this';
var MyObject = exports.MyObject = function (_in) {
console.log(_in);
};
var another_func = exports.sum = function (a, b) {
console.log(a + b);
};
return exports;
}(jQuery));
library.MyObject('foobar'); // "foobar"
library.sum(3, 5); // 8
console.log(private); // Uncaught ReferenceError: private is not defined
Although I don't know why you want to do it.. Maybe this helps
// Define Class globally
// window.MyObject also works
var MyObject = (function($) {
// Passes jQuery in
return function () {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();

Namespacing Variables - javascript

I see a lot of namespacing examples with functions but, is it o.k. to declare variables (global to my program) in this way?
var mynamespace = {};
mynamespace.var1 = 5;
or should all variables be placed in functions within the namespace?
You should avoid global variables...
Use some sort of module pattern instead, e.g.
(function () {
"use strict";
var myVar = 'blob';
}());
See http://yuiblog.com/blog/2007/06/12/module-pattern/
EDIT:
More Clarification:
var NS1 = NS1 || {};
NS1.myModule = function () {
"use strict";
var myVar = 'blob';
return {
myPublicMethod: function () {
return myVar;
}
};
}();

Call jQuery defined function via string

I'd like to call functions I've defined within the document ready function of jQuery, but am having a bit of trouble. I have the following code:
jQuery(document).ready( function($) {
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
var test_call = '2';
var fn = 'test' + test_call;
// use fn to call test2
});
I don't want to use eval, and window[fn] doesn't seem to be working. The two test functions don't appear to be indices in the window variable. I appreciate the help and knowledge.
All I can think of that doesn't use eval() or some form of eval (passing a string to setTimeout() is a form of eval()), is to register the relevant function names on an object and then look up the function name on that object:
jQuery(document).ready( function($) {
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
// register functions on an object
var funcList = {};
funcList["test1"] = test1;
funcList["test2"] = test2;
var test_call = '2';
var fn = 'test' + test_call;
if (fn in funcList) {
funcList[fn]();
}
});
or the registration could be done in the definition of the functions. If they were global functions, they would be implicitly registered on the window object, but these are not global as they are scoped inside the document.ready handler function:
jQuery(document).ready( function($) {
var funcList = {};
funcList.test1 = function test1() {
alert('test1');
}
funcList.test2 = function test2() {
alert('test2');
}
var test_call = '2';
var fn = 'test' + test_call;
if (fn in funcList) {
funcList[fn]();
}
});
Or, you could move the functions to the global scope so they are automatically registered with the window object like this:
function test1() {
alert('test1');
}
function test2() {
alert('test2');
}
jQuery(document).ready( function($) {
var test_call = '2';
var fn = 'test' + test_call;
if (fn in window) {
window[fn]();
}
});
The best way, if not Eval, would be to use setTimeout with zero milliseconds, as you can specify the function as a string.
setTimeout('myfunction()',0,);

Javascript with new or not

I have the following function
var myInstance = (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
what's the difference if I add a new to the function. From firebug, it seems two objects are the same. And as I understand, both should enforce the singleton pattern.
var myInstance = new (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
While the end result seems identical, how it got there and what it executed in is different.
The first version executes the anonymous function with this being in the context of the window object. The second version executes the anonymous function, but this is in the context of a new empty object.
In the end, they both return another object(your Singleton). It's just a slight difference in execution context.
To test this out, but an alert(this); right before the declaration of the privateVar variable.
#Tom Squires: That's not necessarily true and is poor practice not to declare your variables. A script with the "use strict"; directive does cause the JS engine to complain (assuming that the engine supports "use strict";

Categories

Resources