What does it mean, to write JavaScript in your own name scope, apparently it avoids conflicts and conforms to W3C standards but I have no idea what it means or how it is done?
What I think you mean is namespacing. It means that you should contain your code in a namespace so that you won't pollute the global scope (well, you did pollute it with only one variable and that's about it). Every function and other stuff you intend to create will live in that namespace.
A simple namespace example, in object literal
var ns = {
foo : function(){...},
bar : function(){...}
}
You only declared one global, ns. The rest are stored in it and accessible via ns
ns.foo();
ns.bar();
Real life examples can be seen in JS frameworks. For example, we have jQuery and Underscore
//jQuery uses "jQuery" and "$" as namespaces and has "each()"
$.each();
//Underscore has "_" as a namespace and also has "each()"
_.each();
Although they have the same function names, but they live in separate namespaces. This avoids conflict, and helps you identify what belongs where.
It's a way to minimize the use of global variables (thus avoiding possible conflicts).
var myNS = {}; // Your namespace (an object) = a global var.
myNS.title = "Demo"; // Your variables come here as object properties.
myNS.date = "2012-05-21";
The object properties can be of any type: scalar types, arrays, objects, functions...
I guess it means writing functions in your own object, instead of writing global functions:
var myScope = (function() {
function privateFunction1() {...}
function privateFunction2() {...}
function a() {...}
function b() {...}
function c() {...}
return {a: a, b: b, c: c};
})();
Related
I'm using some libraries (like for example Less.js & Dojo) which require global config variables. For example:
less = { ... };
dojoConfig = { ... };
This works ok, but I'm wondering, should I declare this variables explicitly on window?
window.less = { ... };
window.dojoConfig = { ... };
What are pros & cons of each approach? what are pros & cons of referencing this variable from the actual code like (not considering possible name conflicts with local variables):
var somethingNew = dojoConfig.something;
The only thing I can think of is that code without window is prettier :)
If you start running your code in strict mode, you'll find that it's illegal to create implicit globals by excluding var or window..
IMO, it's just always a better practice to make your declarations explicit. For globals, that's either window.foo or var foo if you're in the global variable scope.
As far as referencing the existing global, it's just like any other variable at that point, so you don't really need window. for that purpose, though you could use it if the variable is shadowed by a local variable with the same name.
Explicitly attaching properties to window is easier to maintain than implicit global variable declarations. If you need to be flexible about the environment, you can use the following syntax:
//Here, "this" refers to the window when executed inside the browser
(function() { this.prop = "value" })()
console.log(window.prop === "value") // true
Within that function, you can add your private logic and expose the needed variables as needed. Also, you can name that function and attach those properties to any object you bind it to via function.prototype.bind
By the way, implicit globals also won't work in strict mode.
What is the difference between
var module = (function(){
return {}
})()
and
(function(context){
var module = {}
context.module = module;
})(this)
A property of this is not equivalent to a variable. In the global scope (i.e. where this references window), they are similiar. Yet, for example they will have a different behavior when you try to delete them:
> this.module = {};
> delete this.module
true
> var module = {};
// cant be deleted
Apart from that, both snippets create an empty object, wrapped inside a closure where you could define local (private) variables/functions etc. In your second function the object is also assigned to the local variable module, but that could be done in the first one as well.
#Eric: Your approach, using the new operator, is similiar to the first one regarding the variable. However, it will create an instance of that anonymous function instead of returning a plain object. It will inherit properties from a custom prototype, so for example module.constructor will then point to the anonymous function (which cannot be garbage collected, but e.g. even reused to create a clone). I would not recommend to use this.
Top one is revealing module pattern. It lets you define private functions (as much as you can in javascript) and choose which ones are made public via the return call.
var module = (function(){
function foo() {}; // Public, since it's returned
function bar() {}; // Private, since it is not returned
return {
foo: foo
}
})();
The bottom one, as far as I can tell, just assigns an object literal to another object's namespace. It's probably the start of a singelton pattern.
(function(context){
var module = {};
context.module = module;
}(this)
The module could actually be defined with the revealing module pattern, hard to say since in your example it's just an object literal.
I'm reading more open source javascript frameworks and found more ways of how to create anonymous functions, but whats is different and best way?
(function() {
this.Lib = {};
}).call(this);
(function() {
var Lib = {}; window.Lib = Lib;
})();
(function(global) {
var Lib = {}; global.Lib = Lib;
})(global);
(function() {
this.Lib = {};
}).call(this);
Defines the Lib property of the Object it's called on, and is immediately called on this which is typically the window. It may instead refer to the Object that owns the method in which it is called.
(function() {
var Lib = {}; window.Lib = Lib;
})();
Defines the Lib property of window regardless of where it's called (although it's also called immediately).
(function(global) {
var Lib = {}; global.Lib = Lib;
})(global);
Defines the Lib property of the object passed to the function. It's called immediately, but will result in an error unless you've defined a value for global in the current scope. You might pass window or some namespacing Object to it.
These aren't actually different ways of defining "anonymous functions", they all use the standard way of doing this. These are different methods of assigning values to global (or effectively global) properties. In this sense, they are basically equivalent.
Of more significance would be, for instance, how they define methods and properties of the objects they return/construct/expose (that is, how they build Lib itself).
All of these functions return undefined and only the first could be usefully applied as a constructor (with the use of new), so it would seem they are nothing more than initializers for the frameworks.
All of them are effectively equivalent (but less efficient and more obfuscated) to:
var Lib = {};
Immediately invoked function expressions (IIFEs) are handy for contianing the scope of variables that don't need to be available more widely and conditionally creating objecs and methods, but they can be over used.
Note that in the last example, I think you mean:
(function(global) {
...
})(this);
Check out this question: Why do you need to invoke an anonymous function on the same line?
It contains a whole lot of information about anonymous functions. Check out this question as well: var functionName = function() {} vs function functionName() {}
I'm trying to improve my understanding of the global namespace in javascript and I'm curious about a few things:
is there a "GOD" (i.e. a parent) object that all objects (since all things except primitives are objects) to answer to and if so would that object be "window" ?
why is it bad idea to have vars/functions on a global level?
if it is really a bad idea to have vars/functions in global scope then would closures be the best way to avoid this? example:
function parent(){
var x = 'some value';//this var would be considered global to all children functions but not in the true global namespace
function child1(){
x.someMethod()
}
function child2(){
x*something;
}
function child3(){
x+=something;
child2()
child1()
}
child3()
}
parent()
Is there a god (i.e. a parent) object?
Yes. More technically, it's the global object that all these primitives are members of; it just happens that in the browser, the window object is the global object.
> window.String === String;
true
Why is it bad idea to have vars/functions on a global level?
Because if you're adding lots of 3rd party libraries/ scripts, they all share the same global object, there's the chance of name collisions. This is a real life problem with all the libraries which use $ as an alias (jQuery, Prototype and more).
If it is really a bad idea to have vars/functions in global scope then would closures be the best way to avoid this?
x shouldn't be considered global. It's part of the closure formed by declaring the child functions inside the parent() function. The problem part of your snippet is that parent() is global; what happens if some other code re-declared parent()? This would be better:
(function () {
function parent(){
var x = 'some value';
function child1(){
x.someMethod()
}
function child2(){
x*something;
}
function child3(){
x+=something;
child2()
child1()
}
child3()
}
parent()
}());
The fact x is accessible within the child functions isn't bad; you should have written those functions yourself, so you should be aware of the existence of x. Bear in mind that if you re-declare x within those child functions with var, you won't affect the x in parent().
Yes, in a browser environment the "god object" is window. It's typically called the global object, not god object though ;) In non-browser environments such as nodejs, the global object may use some other name than window.
If you put everything as globals, you risk running into colliding names. There is also the matter of encapsulation - in other words, by putting variables into only the scope where it's needed, your code is usually better off.
Yep, this is pretty much the preferred approach. You can also use IIFE's
As far as I know, I'd say yes, window is the parent object. However, inside an Iframe you have your own window object, distinct from surrounding window which you can access through window.parent
It's a bad idea to have a LOT of global var because of potential name collision and therefore hard to detect bugs. In general it's safer to design some namespace (see
the $ from jQuery, etc) and modularize code.
Be careful, parent is a potential existing field of window. This taken appart, function are object so the same observation than in 2) apply here.
If you NEED to put variables in the global namespace, and you likely will at some point, create a single object variable and add your other variables to it as properties or methods. Give the object a name that is not likely to be used by anyone else (admittedly, this is where collision problems arise, but that can be mitigated by careful, standardized naming).
e.g. Instead of:
var thing1 = 'table';
var anotherthing = 'chair';
var mypet = 'dog';
var count = 4;
var show_something: function( _txt ) { return _txt.trim(); };
Do this:
var cmjaimet_obj = {
thing1: 'table',
anotherthing: 'chair',
mypet: 'dog',
count: 4,
show_something: function( _txt ) { return _txt.trim(); }
};
Then later call them as properties:
e.g. Instead of:
count += 2;
anotherthing = 'sofa';
console.log( show_something( 'Thing: ' + anotherthing ) );
Do this:
cmjaimet_obj.count += 2;
cmjaimet_obj.anotherthing = 'sofa';
console.log( cmjaimet_obj.show_something( 'Thing: ' + cmjaimet_obj.anotherthing ) );
I have my own Javascript library, which I want to minify by using Google closure compiler with Advanced optimization. By looking at the docs I see how to declare functions which are used outside of the library.
However I couldn't find a way how to preserve global variables declared in my library. Closure compiler just removes them, because it thinks they are never used. Anybody can help ?
Edit: example code:
var variable_1 = true;
This is defined globally right at the beginning of my library, but it's never used in the library itself. It is used outside the library when it is included in some page. But that Closure compiler doesn't know and thats the reason it removes these declarations.
The closure compiler cannot remove global variables declared as window["variable_1"] = true
I recommend you write to window directly for global variables and I also recommend you use string literals for your variable names so that closure doesn't minify it.
Although you can refer to a "true" global variable through replacing all usage of that global variable with window["varname"], it is usually not a good idea to "pollute" the global namespace. The Closure Compiler is designed to discourage you from doing this.
CAVEAT: window["varname"] and var varname are not the same, as "window" may not always be the global object in non-browser environments. As a matter of fact, the Closure Compiler assumes that the global object and "window" are different. For example, window["varname"] will compile to window.varname instead of var varname. They are NOT the same, although in a browser they work similarly.
It is best to make a global namespace object, then only export that one object. All your "global" variables should become properties under this global namespace variable. Benefits:
All those global variables are renamed to shorter versions
Inlining of constants can happen
The Closure Compiler automatically "flattens" the namespace anyway, so your code won't be any slower
Superior obfuscation
Your code also works in non-browser environments. Remember, "window" may not always exists (e.g. in server-side code) and the "global object" may not always be "window"
If you have global variables that the user must read/set to use your library, it is also discouraged. It is better to expose an API on the global namespace object, then expose the public API's as usual through the window object: window["myLib"]["setConfig"] = myLib.setConfig.
In your case, if you have global variables used in other parts of your non-Closure-Compiled code, you have to consider:
Is it better to put the declaration of those variables outside of the file being compiled by Closure
Why are you not putting the declaration of those variables together with the code using them
Should you actually be Closure-compiling all the code instead of only a portion (it is possible? Do you use another library?)
I've just come across this, and I have my own solution.
Create you're entire library within a self-executing function, putting all the object properties as strings (at least once for each property) like so:
(function () {
var myLibrary = {
'myMethod' : function () {
...
}
}
myLibrary.myMethod['propertyOfTheMethod'] = '';
}());
The usual way to make this accessible from the outside would be to put var myLibrary = before the function and return myLibrary at the end of it so that it gets assigned to a global variable. But the function is executed in the global scope (because it's self-executing), so we can create a property of this using a string literal. So in full:
(function () {
var myLibrary = {
'myMethod' : function () {
...
}
}
myLibrary.myMethod['propertyOfTheMethod'] = '';
this['myLibrary'] = myLibrary;
}());
But, this won't work under "use strict";. The best way to get the global variable in strict mode is with var global = Function('return this')(); then assign your variable to that.