I've been reading through some global scare articles, you can thank Crockford for this question.
For instance, I have a function I've defined as:
function httpRequest() {}
This is a pretty generic function name, which could potentially be used in a thirdparty library. Should I just make it a habit to attach the function to an app namespace?
APPNAME.httpRequest() {}
I read through Google's style guide for JavaScript and they recommended this for variables, what about functions and classes?
APPNAME.MyClass = (function () {
'use strict';
function MyClass() {}
MyClass.prototype.myMethod = function () {};
return MyClass;
}());
EDIT:
Let's say I plan on combining with a lot of other libraries.
JavaScript variables are closure scoped. So you can always use an IIFE to encapsulate them:
(function(){
function httpRequest() { /* */ }
httpRequest(...);
})()
//httpRequest is not defined here unless it was defined above the block
You can also export stuff to the global namespace
var httpUtils = (function(){
return whatever; // whatever is exported, the other variables are internal
})()
Creating objects that encapsulate behavior like this and exposes some is called a module pattern.
You can use module loaders to manage your modules. One example is RequireJS.
require(["httpUtils","logger",function(http,log){
http.request(...); // uses from other module
log(..); // use other module
return { }; // the return values can be used in other modules, require by file name
// or explicit configuration
});
Namespacing is also an option, but it is generally less desirable.
Related
I'm creating a wrapper for an API that will be used in a couple different applications.
I'm using a global object and placing the various functions into that object as different keys. So I'll have:
window.globalContainer = {
APIEndpoint1: function(){
make API call and resolve result
},
APIEndpoint2: function(){},
...
}
All the meat of the API calls are directly in the functions. That is, you could go to window.globalContainer.APIEndpoint1 from the console and see the entire function.
Is this generally bad practice for something that's used across multiple applications and acts as a helper library? Or is this acceptable? I looked at jQuery in the console and it seemed to do much of the same. If it is frowned upon, how do I implement private functions within the global object?
A good place to start is anonymous closures:
(function (global) {
var foo = global.foo || {};
//accessible
foo.publicVar = 5;
foo.publicFcn = function (a, b) {
privateFcn(a, b);
...
};
//not accessible
var privateVar = 5;
function privateFcn(a, b) {
...
}
global.foo = foo;
})(window)
With these you can pretty intuitively build a library and not pollute the namespace.
You explicitly say which variables and functions you want to be made accessible.
You can use an IIFE to implement private functions/properties.
window.globalContainer = function () {
//what ever you define here is not accessible outside. Only the API in
//the returned object is accessible outside
function private1() {
make API call and resolve result
}
return {
APIEndpoint1: function(){
private1();
},
APIEndpoint2: function(){},
...
}
}();
I read some JS module design patterns recently. I came across this small code snippet as below.
(function(window) {
var Module = {
data: "I'm happy now!"
};
window.Module = Module;
})(window);
Still not quite understand this code well, my questions are:
How to use/call this module outside this particluar JS file? Need I
assign a variable to this module? e.g. var module1 = (...)(...);
Could anyone explain what the window parameter here stands for?
Is it a good practice to have two/three such kind of modules in the
same file?
The main reason to create an anonymous function in this case is to prevent global object pollution. It's not really a module pattern.
The problem arise when you declare a variable. Without the function scope, the variable will be added to the global object (window). If you were to declare the variables within a function. It would add the variable to the function scope without polluting the global object window.
What happen is that a javascript file could add a variable named foo and on a different file use that variable named foo too. Unless you really want to have a variable shared by two javascript files, it would probably create conflicts and bug that are difficult to fix.
For example: a.js
var foo = "one"
b.js
var foo = "two"
c.js
alert(foo)
In this case, the alert box might show either "one" or "two", depending of the order in the javascript files are included.
But having this a.js:
(function () {
var foo = "one"
})()
b.js
(function () {
var foo = "two"
})()
c.js
(function () {
alert(foo)
})()
This would create an error as you cannot alert a non declared variable.
One way to detect undefined variables, is to make sure to execute the javascript code in strict mode.
To do that, add the string "use strict" at the top of the file or function.
function () {
"use strict"
...
}
Undeclared variable will raise errors and it should be possible to fix the code that way.
Also, if you forget to declare a variable with the var keyword, it might end up adding the variable to the global scope even if the code is scoped into a function. The only way to prevent global scope pollution is to run the code in strict mode.
In the code snippet that you provided, the module with name Module is explicitly added to the window object. You can access the window object from any place in javascript unless the window name is ghosted by an other variable.
Now, back to the modules. If you want to define modules, it can be done in many ways. As an exemple, you could create an object on the window object called modules. In this object, you'll insert your modules.
module.js
window.modules = {}
foo.js
(function (window) {
var module = {}
...
window.modules.foo = module
})(window)
This variant isn't super good as you have to manually add the module to the modules object. You have to manually modify the window object, and that can be subject to errors.
modules.js
window.modules = {}
function define(name, constructor) {
var module = {exports: {}}
constructor(module)
window.modules[name] = module.exports
}
function require(name) {
return window.modules[name]
}
foo.js
define("foo", function (module) {
module.exports.one = function () {
return 1
}
module.exports.plus = function (a, b) {
return a + b
}
})
bar.js
define("bar", function (module) {
module.exports = function () {
var foo = require("foo")
return foo.plus(foo.one(), foo.one())
}
})
This is a module definition that looks a bit like module defined with http://requirejs.org/. It is quite basic as it doesn't take into account module dependencies so if bar is loaded and used before foo. Then the require method won't be able to return the module.
Also, if you want to store modules without having them visible into the global scope, you can only define the require and define method on the window object and hide modules into an anonymous scope like this:
(function (window) {
var modules = {}
function define(name, constructor) {
var module = {exports: {}}
constructor(module)
modules[name] = module.exports
}
function require(name) {
return modules[name]
}
window.define = define
window.require = require
})(window)
This way, define and require are the only function that can give you access to modules. Other modules won't be able to modify other modules without requiring them first. This can be useful when using third parties script that could conflict with your module system.
In fact this is not a module, but a Self-Invoking Ananymous function or an Immediate function which gets an object in parameter and assign a Module property to it:
The page window is a parameter passed to this function.
So an object named Module containing a data property is assigned to window.
JavaScript Self-Invoking Functions:
A self-invoking expression is invoked (started) automatically, without being called.
Function expressions will execute automatically if the expression is
followed by ().
You cannot self-invoke a function declaration.
You have to add parentheses around the function to indicate that it is
a function expression
So As you can see Immediate Functions can't be called as its name states it will be immediately executed and by its self, no other function or scope can execute it.
For better reference take a look at :
Javascript Self Invoking Functions.
Self-Invoking Functions section in JavaScript Function Definitions.
And concerning your last question about its benefits and good practices as shown on the given Article reference:
Where to use self-executing functions?
One obvious situation is when you want to auto-run a function like I
showed in above example but that is trivial. If you are in a situation
where you want to run a piece of code repeatedly like updating
something in the database based on user interaction or fetching
records from database every 10 seconds or you want to load new stories
via ajax similar to how facebook does on its homepage or some other
similar situation, one would normally go for setInterval function
something like this:
setInterval(doStuff, 10000);
Above, doStuff function will get called every 10 seconds. That is the
normal approach most developers seem to go with. However, there is a
huge problem with that.
The setInterval will call doStuff function exactly at specified time of 10 seconds again and again irrespective
of whether doStuff function actually finished doing what it is
supposed to do. That is bad and will certainly get you into unexpected
results.
That is one example of where setInterval is "bad" and should be
avoided.
This is exactly where self-executing functions come in handy. We can
do the same task with the help of self-executing function along with
setTimeout like this:
function foo(){
// your other code here
setTimeout(foo, 10000);
}();
This code will also repeat itself again and again with one difference.
setTimeout will never get triggered unless doStuff is finished. A much
better approach than using setInterval in this situation.
Calling it from another file:
And if this function is on another file it will be called automatically if this file is included.
Why do we use Self-Invoking Functions in JavaScript?
And if you ask yourself why do we use these functions, self-invoked function are used to manage Variable Scope.
Take a look at the answer here for further information.
I was just looking at the code of a simple demonstration of modular pattern, have a look :
// Global module
var myModule = (function ( jQ, _ ) {
function privateMethod1(){
jQ(".container").html("test");
}
function privateMethod2(){
console.log( _.min([10, 5, 100, 2, 1000]) );
}
return{
publicMethod: function(){
privateMethod1();
}
};
// Pull in jQuery and Underscore
})( jQuery, _ );
myModule.publicMethod();
The code is pretty straightforward, what I don't understand is what's the need for a publicMethod? Why are privateMethod1 and privateMethod2 inaccessible? I understand that privateMethod1 and privateMethod2 are classic js functions and publicMethod is more of a variable assigned to hold a function.
privateMethod1() and privateMethod2() are local functions declared inside the module function wrapper. As such, they are only visible and callable from within that function wrapper. They can't be reached from outside the module wrapper.
This is the same as a local variable inside a function.
function someFunc() {
// a function declared inside another function is ONLY available
// inside that function
function localFunc() {
// do something
}
// this is just like a local variable which is only available within
// the scope of the function itself
var myVariable = 2;
}
// can't call localFunc here - this will be an error
// because it is defined in a different scope and not available here
localFunc();
Private methods can be useful when you want to create functions or methods that the public methods can use, but you do not want outside callers to be able to also call or use those functions/methods.
Private variables can be used to store state that the public methods or private methods want to reference, but you don't want the outside callers to have access to or be able to mess with.
What is the main difference between a module like this
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {}
my.moduleProperty = 1;
my.moduleMethod = function () {};
return my;
}());
and a simple function like this
function MODULE_Func() {
var my = {},
privateVariable = 1;
function privateMethod() {}
my.moduleProperty = 1;
my.moduleMethod = function () {};
return my;
};
var MODULE = MODULE_Func();
I read an article about modules and in it an author describes a module's advantages as: "the module maintains private internal state using the closure of the anonymous function."
i.e, I think he means that 'privateVariable ' and 'privateMethod' is internal for the module and not acceptable from outside. But in the simple function 'privateVariable ' and 'privateMethod' are also internal and not acceptable from outside. The only difference I can see is that the module is a anonimous function so it: 1) doesn't pollute a global state 2)you can't invoke the module twice.
But the author describes a module pattern as a great thing but I can't see for what. And because you can't invoke the module twice, you can't have more than one instances of modules, I think in many cases it is even a disadvantages.
But the author describes a module pattern as a great thing but I can't see for what
Well, you've said it yourself: 1) doesn't pollute a global state 2) you can't invoke the module twice. Those are advantages if you want them.
And because you can't invoke the module twice, you can't have more than one instances of modules, I think in many cases it is even a disadvantages.
Those modules are static. Indeed, they should not have internal state but only local (internal) variables, e.g. for helper functions.
In cases where you need multiple instances, don't use a singleton-like module. Use a constructor ("class") instead, like in your second example. You might however still use a module as a namespace for your class.
the difference is that the first one
var MODULE = (function(){})();
MODULE refers to whatever an the anonymous function being executed will return. if it returns nothing then **MODULE will be set to undefined. the function being executed is an IIFE(Immediately Invoked Function Expression), More info here. It executes on page load since MODULE is referred by the global window.
and the second is a function MODULE_func(){}, MODULE_FUNC is the name of the function itself, this function is now a property of the global window meaning that it can be referred by the global window as so window.MODULE_func(){};, the other can be referred as well but note the difference, the other is an anonymous function without a name and has TWO referrers. This one has a name and one referrer..
var MODULE = (function(){})();
can be referred by
window.MODULE;
MODULE;
function MODULE_func(){}
can be referred by
window.MODULE_func; ONLY
I have been writing javascript for a while now and more recently been playing with coffeescript. I noticed that coffeescript compiles functions in the following way:
(function() {
}).call()
I have also noticed people write functions in this way:
(function() {
})()
From what I understand these are anonymous functions that call themselves. Firstly, what is the difference in between having .call() and just () is .call() just a more semantic way of writing ().
Also why does coffeescript wrap the entire file in an anonymous function, when it isn't usually necessary? Are there any performance or other advantages to this? When should these sort of self calling anon functions be used?
Thanks
Using .call() changes the context of the IIFE to the this value of the parent scope.
The first this will be [object Window], the global scope in browser environments:
(function () {
console.log(this);
})();
The second, will be the exact same:
(function () {
console.log(this);
}).call(this);
The difference is that in ECMAScript 5's strict mode, the first example this will be undefined:
(function () {
'use strict';
console.log(this); // undefined
})();
However when using Strict Mode and .call(), this is again the global scope with the correct this context:
(function () {
'use strict';
console.log(this);
}).call(this);
Here's a jsFiddle showing this. The main difference is that the normal IIFE loses it's this context, some CommonJS platforms evaluate files with a specific this.
CoffeeScript does this to ensure that your code has the same this context as the scope where it's placed (the parent scope) - because functions don't normally inherit their this object from the surrounding context.
Using the pattern(s) above, you should wrap your function logic in there to avoid placing all your code in the global scope and having variable/naming conflicts, to which you can then create things such as Modules and return only the APIs that you need, for instance:
var Module = (function () {
'use strict';
return {
someMethod: function () {
// do something
}
}
})();
// call it:
Module.someMethod();
Each function creates it's own scope, so wrapping your blocks of code in these will protect your variable/function names from conflicting with eachother. We can also access "private" methods from within these closures:
var Module = (function () {
'use strict';
var _privateMethod = function () {};
return {
someMethod: function () {
_privateMethod();
}
}
})();
We would do this when we don't want the methods to be publicly accessible by our users too.