Unnecessarily comprehensive look into a rather insignificant issue of global objects creation
I noticed this code few days ago — in one of the “modules” of an internal app I’m working on — which looked like this:
if (MyApp == null) {
var MyApp = {}
}
This was at the beginning of the file, and was obviously a way to define global “namespace” object, if one didn’t exist. The condition in this particular case, however, looked rather unusual — if (MyApp == null). It got me thinking about the ridiculous number of ways in which it is possible to define a global object in Javascript.
I’m sure you’ve seen the variations of this kind:
if (typeof MyApp == 'undefined') {
var MyApp = { };
}
or:
if (!window.MyApp) {
window.MyApp = { };
}
or maybe even something as strange as:
if (MyApp === undefined) {
MyApp = { };
}
But have you ever wondered about the difference between these? Are any of them “better” than the other ones, and why? Is there a particular way you prefer, and for which reason?
If we were to look into some of the possible global object creation patterns, it turns out there’s quite a bit of interesting little details (and traps) here and there. What do you mean they’re not interesting? Of course they are! :)
As a fun exercise, let’s go over some of the more popular variations, explaining the inner workings of each one of them. We’ll take a look at troublesome ones; those that are more compatible than others; and those that differ depending on whether implementation follows ES3 or ES5 rules. Hopefully, you’ll also learn a thing or two about ECMAScript while we’re at it.
How many ways to skin a cat?
So what are the options for creating a global object if one doesn’t exist? Well, let’s see. There are conditions, used as expression in an if statement. And there are actions used as the inner statement in an if statement.
if (condition) {
action
}
Even if we’re not using if statement, the general pattern of condition + action is still in effect:
condition && action
!condition || action
// etc.
The lists of conditions and actions might look like this (I’ll be using MyApp “name” as an example):
Conditions:
!MyApp
!window.MyApp
!this.MyApp
!global.MyApp
typeof MyApp == "undefined"
typeof MyApp != "object"
MyApp === undefined
MyApp == null
"MyApp" in window
window.hasOwnProperty("MyApp")
Actions:
var MyApp = { }
window.MyApp = { }
this.MyApp = { }
global.MyApp = { } // where `global` references global object
MyApp = { }
There are undoubtedly other similar variations, such as using bracket notation instead of dot notation — if (window['MyApp']) { ... }, or more obscure ones like eval('var MyApp = ...'), but we’ll omit those for the sake of brevity. Arguably, some of the items in this list are rather similar to each other, like window.MyApp, this.MyApp, and global.MyApp — after all, they are all assignments to a property of global object — but I’d like to show the important difference in each one of them, which is why we’ll look at them separately.
I promise not to go over all of the 50+ possible combinations. Only a handful of them.
Patterns overview
1) typeof + variable declaration
if (typeof MyApp == 'undefined') {
var MyApp = { };
}
This is probably the most popular variation. Good old variable declaration, and a typeof check. When executed as global code, it creates a global variable (if one doesn’t exist) and assigns an object reference to it. What’s important to understand about this snippet is that variable declaration — similar to function declaration — follows the so-called “hoisting” behavior. In other words, MyApp variable is created before any statements in the current scope are executed. This is why the snippet is functionally identical to:
var MyApp;
...
if (typeof MyApp == 'undefined') {
MyApp = { };
}
When MyApp is already defined and references something, typeof MyApp != 'undefined' check does not succeed and MyApp is not overwritten. The declaration of MyApp does nothing since binding already exists in this scope. However, if MyApp doesn’t yet exist, typeof MyApp evaluates to “undefined”, and MyApp is assigned a reference to a newly created object. The reason typeof MyApp evaluates to “undefined” is because at that point MyApp is already declared and has an undefined value (as all undeclared variables do).
2) boolean conversion + variable declaration
if (!MyApp) {
var MyApp = { };
}
Another common version is the same as the previous one, only with typeof check replaced by a boolean conversion one. This one is clearly shorter but is it just as reliable? I remember being confused about it a while back. Shouldn’t MyApp throw a ReferenceError if MyApp isn’t declared — I thought. My fears were certainly unfounded. The “hoisting” behavior of variable declarations prevents ReferenceError from occurring here. Similarly to the previous example, let’s see a functionally identical version of a snippet:
var MyApp;
...
if (!MyApp) {
MyApp = { };
}
var MyApp that’s inside the block, hoists MyApp declaration to the top of the scope. By the time execution gets to the if statement, MyApp is already declared and has an undefined value. if (!MyApp) can never throw a ReferenceError, since the variable is always declared.
3) boolean conversion + undeclared assignment
if (!MyApp) {
MyApp = { };
}
Sometimes a perfectly good second version is taken to the “next level” with this unpleasant variation. Unlike previous example, there’s no variable declaration here; only an assignment. When MyApp doesn’t exist, !MyApp expression throws ReferenceError for exactly this reason — the variable is never declared, and the access to it should throw! This version is hardly practical, but it’s good to understand why it doesn’t “work”.
Undeclared assignment
Before we move further, take a closer look at MyApp = { } line. Anything looks suspicious there?
This is a so-called undeclared assignment. Instead of declaring a variable via a variable statement (i.e. var MyApp = { }), MyApp is being assigned a value directly. In ECMAScript, when something is being assigned to non-existing variable, the variable with that name is created on a global object and becomes available to any code. Well, to be more precise, it becomes a global property, rather than a variable, but this subtle difference is not important now.
So MyApp = { } creates a global MyApp property, then assigns a newly created object reference to it.
Note how very much MyApp = { } is different from var MyApp = { }. The former one — undeclared assignment — creates a global property, whereas latter one — variable declaration — creates a local variable.
Undeclared assignments are historically considered a bad practice. They lead to confusion and increase the risk of global collisions. There are also certain browser bugs, such as that in IE (MSHTML DOM), where undeclared assignment results in an error if element with same id/name exists in the document. There’s a big chance for beginner to forget var and end up creating an unwanted global property. Or simply consider var’less version to be similar to that with the var. Or not even know about having to use var — after all, plain assignment seems to work just fine.
Since undeclared assignments are such a misleading part of the language, ECMAScript 5 — newest version of ECMAScript — specifies that when they occur in a strict mode, a ReferenceError should be thrown. This makes for more robust code with less chance for unexpected errors. And since strict mode is more or less a future direction of the language, it makes sense to avoid undeclared assignments as if they never existed.
4) typeof + undeclared assignment
if (typeof MyApp == 'undefined') {
MyApp = { };
}
Another harmful variation, and unfortunately the one that actually “works”. Note how there’s still an undeclared assignment, but the condition is now replaced with a typeof check. typeof check is exactly what makes all of this work, unlike plain variable access in the previous example. In ECMAScript, when typeof is passed an undeclared identifier, it’s specified to return string “undefined”. This kind of leniency exists on purpose — typeof is meant to be used with undeclared identifiers; it doesn’t throw (as regular variable access does) but returns “undefined” instead.
So when MyApp doesn’t exist and if expression succeeds, MyApp = { } is evaluated and creates a global MyApp property. The problem here is that MyApp = { } is still an undeclared assignment and so has all the same problems as undeclared assignment from the previous example.
5) property access on window
if (!window.MyApp) {
window.MyApp = { };
}
Stepping away from variable declarations and undeclared assignments, which other ways are there to create a global property?
Well, by assigning directly to a global object of course. In browsers global object is often referenced through global window property. So one of the ways to create a property on a global object is by assigning to property of window. This solution is almost perfect, except for two drawbacks.
First, it makes code less portable, as there is a reliance on presence of global window property. If you wanted to run it in a non-browser environment (V8, Rhino, WScript, etc.) window is likely to be non-existent there.
Second problem is a bit more vague. It’s relevant to browser environments only, and it’s about window not referencing global object directly. HTML5 defines window to reference not global object, but so-called WindowProxy object. Even though all operations performed on WindowProxy must also be performed on the Window object, there are few existing quirks — notably in Internet Explorer — where global (variable) object and window are not fully interchangeable (more evidence).
Curiously, current HTML5 draft also says that window typically references a Global Object, which makes it a non-requirement. In practice, however, window almost always references Global Object (or at least an object that acts as if it was a global object).
6) property access on this
If you don’t want to rely on browser-only window, the most straightforward way to assign to a global object is by creating a reference that definitely gives us a Global Object. How to create such reference? Well, since we’re in global code, we can freely use this keyword.
if (!this.MyApp) {
this.MyApp = { };
}
This works beautifully, and should create a global object in any respectable (i.e. ECMAScript-compliant) implementation. Note, however, that this code can only be run in global scope to ensure that this references global object. Of course you could also run it non-globally as long as this keeps referencing global object:
var myObject = {
myMethod: function() {
...
if (!this.MyApp) {
this.MyApp = { };
}
}
};
// call method with `this` referencing global object rather than `myObject`
myObject.myMethod.call(this);
The requirement to be able to create global object from within non-global code might seem contrived. Yet, I’ve seen quite few times how javascript files — representing different “modules” — were concatenated together and wrapped into another, global self-executing function. Or the code would be eval’d after being retrieved from the server via XHR. During evaluation, it would be executed in the scope of a caller, not in the global scope.
This kind of “global object passing” could certainly become cumbersome. If only there was a way to get access to global object from within any scope. Well, there certainly is.
7) property access on global
The easiest way to achieve this is by creating a globally-accessible unique property referencing global object:
// from within global code
var global = this;
.. which brings us to the next variation of global object creation:
if (!global.MyApp) {
global.MyApp = { };
}
This snippet could now be executed from anywhere — as long as global binding is not shadowed by anything in the executing scope.
(function(global){
// this obviously won't work since `global` is now a local variable and has a value of `undefined`.
if (!global.MyApp) {
globa.MyApp = { };
}
})();
We solved the problem of not being able to run code from anywhere, but at the expense of having an extra global property. We’ve also introduced a requirement to actually create that global property. If our code is run in unknown environment, where it’s not possible to create this global object shortcut, this kind of solution is out of the question. Additionally, there’s a chance of collisions if another code defines global global property referencing something other than global object.
This is disastrous. What to do?
Global object retrieval
In ECMAScript 3 — it turns out — there’s a very easy way to retrieve global object from within any code. The beauty of the following solution is also that it’s not affected by local shadowing. It’s pretty much the perfect way to get access to global object:
var global = (function(){return this})();
The idea is simple. In ES3, when function is called as a function (not as a method; more precisely — as a non-reference or as a reference with null base object) its this is set to reference global object. When (function(){ ... })() is executed, it evaluates to a non-reference, so it’s invoked with this referencing global object.
Alternatively, we could have created a reference with null base object, which would also execute function with this referencing global object:
function f(){return this}
var global = f();
.. but that wouldn’t be as short and concise.
Great! We can now have global object from within anywhere. Is there a catch?
ECMAScript 5 strict mode
Well, yes, kind of. The catch is ECMAScript 5 and its newly-introduced strict mode. In ES5 strict mode, this no longer references global object in the above two cases:
"use strict";
(function(){return this})(); // undefined
function f(){return this}
f(); // undefined
The rationale for this was, supposedly, to increase security by limiting access to global object. There is, however, a workaround and it involves indirect eval call (which I explained in the past):
"use strict";
var global = (1,eval)("this");
Indirect eval evaluates code in global scope, and MUST set this to reference global object. So (1,eval)('this'), which is an indirect eval call, should evaluate to a global object.
The downside of this workaround is potential shadowing of eval by something other than built-in eval. The solution is certainly not as robust as (function(){return this})() one, which can be used in ES3 and ES5-non-strict code.
So to summarize:
var global = (function(){return this})(); // ES3, ES5 non strict
var global = (1,eval)('this'); // ES5 strict
In our current world of just-appearing ES5-compliant implementations, it’s hard to come up with a reliable cross-platform solution. Should we use ES3-ES5-non-strict snippet or ES5-strict one? The latter one sounds like a more future-proof solution, but reliance on indirect eval makes it a moving target: as we’ve seen before, indirect eval behavior varies across browsers.
Perhaps we can assume that browsers with strict mode support also follow ES5-compliant indirect eval behavior? In that case solution is simple:
"use strict";
var global = (function(){ return this || (1,eval)('this') })();
Implementations that don’t support strict mode, should evaluate left-hand side of || expression — this, which would be a global object and as any object be truthy. Implementations that DO support strict mode, should evaluate right-hand side of an expression since this would be undefined. Right-hand side should then evaluate to a global object — if eval still references built-in function of course.
This solution is arguably too verbose so it might not be desirable in all cases.
8) property access + variable declaration
Another common pattern is the one that combines any of the previously discussed solutions. For example, property check as condition and variable declaration as action:
if (!window.MyApp) {
var MyApp = { };
}
or typeof check as condition and property creation as an action:
if (typeof MyApp == 'undefined') {
window.MyApp = { };
}
Are there any problems with this variation? Benefits?
Well, first version can obviously only work when run from within global code; we need variable declaration to create global binding. The potential problem with this snippet is that we check existence of property on window but create it on global object. If window doesn’t reference global object, there’s a room for discrepancy. We could use previously discussed this or global instead of window — to refer to a global object:
if (!this.MyApp) {
var MyApp = { };
}
In this case, the snippet is not much different from the first example:
if (typeof MyApp == 'undefined') {
var MyApp = { };
}
The only subtle difference here is that this.MyApp check proceeds when this.MyApp evaluates to something falsy (0, ”, NaN, null, undefined, false), whereas typeof MyApp == "undefined" — only when MyApp evaluates to undefined:
var MyApp = '';
...
if (!this.MyApp) {
// this statement is executed; MyApp is overwritten
var MyApp = { };
}
if (typeof MyApp == 'undefined') {
// this statement is not executed; MyApp is not overwritten
var MyApp = { };
}
Since both this.MyApp = { } and var MyApp = { } will create global MyApp binding, the only difference here is that former one makes it deletable, while latter one doesn’t. Other than that, there is no difference — both operate on a global object when run from within global code. At least in theory. In practice, though, there has been some evidence of IE having different objects as global variable object and window object. For best cross-browser results, I would suggest to avoid mixing them up like this.
9) typeof “object”
Sometimes typeof MyApp == 'undefined' check is replaced with the opposite one — typeof MyApp != 'object'.
if (typeof MyApp != 'object') {
...
}
There isn’t much difference here, of course, except that typeof != 'object' check will also catch any other non-object and non-undefined values; pretty much all primitives except undefined:
var MyApp = "trolololololo";
if (typeof MyApp != 'object') {
MyApp = { }; // MyApp is overwritten
}
10) == null and === undefined
Other times, typeof check is replaced with direct comparison with undefined or null values:
if (MyApp === undefined) {
var MyApp = { };
}
// or
if (MyApp == null) {
var MyApp = { };
}
The second example is what I mentioned in the beginning and what got me surprised in the first place. As you probably know, comparing to null via equality operator (==) returns true when value is either null or undefined. This is why it allows to catch undeclared variables which have undefined values.
If you think about it, there’s really no reason to use this kind of check though. Even though it’s shorter than typeof, comparing to undefined is more fragile, since undefined is a writable property in ES3 (which is why — without taking precautions — it has been generally recommended against). Comparing to null is safer but is still unnecessary; !MyApp is just enough and is even shorter.
11) in and hasOwnProperty
There are even more exotic beasts such as those using in operator or hasOwnProperty method.
if (!('MyApp' in this)) {
this.MyApp = { };
}
if (!this.hasOwnProperty('MyApp')) {
this.MyApp = { };
}
Using in is almost identical to using plain boolean conversion — if (!MyApp) .... The only difference is that in will “catch” global properties with any values, whereas boolean conversion-based one — only those that have truthy values. Similarly to typeof ... == "undefined" check, in will catch both — undeclared variables and variables with undefined values.
hasOwnProperty, on the other hand, is a bit more strict. Even though irrelevant in our case, it’s worth remembering that hasOwnProperty will catch only those properties that exist directly on a global object. That means nothing from global object’s prototype chain, which could include Object.prototype, Window.prototype, etc.
this.hasOwnProperty('localStorage'); // false
'localStorage' in this; // true
this.hasOwnProperty('alert'); // false
'alert' in this; // true
this.hasOwnProperty('toString'); // false
'toString' in this; // true
var x;
this.hasOwnProperty('x'); // true
'x' in this; // true
12) || operator
global.MyApp || (global.MyApp = { });
this.MyApp = this.MyApp || { };
typeof MyApp == 'undefined' && (global.MyApp = { });
A slightly different way to write #5, #6, or #7 is using || operator. The functionality is the same; this is only a matter of preference.
Takeaway points
So there you have it. A quick rundown through some of the most popular options. To summarize:
- Avoid undeclared assignments. They are a “dying” part of the language.
- Assigning to
windowis not completely cross-platform; usingthis(or retrieving global object) is more portable. - Retrieving global object is iffy. You can use
(function(){ return this || (1,eval)('this') })()which should work in ES3, ES5 and ES5-strict. - Some variations (e.g. variable assignment) work only in global scope; others (e.g. assignment to window) — from within any.
- No need to perform
typeof "undefined", or=== undefinedchecks; plain!operator works just as well, as long as variable is created via declaration. - When in global scope, the easiest & simplest version to create global object is
if (!MyApp) var MyApp = ... - When object needs to be deleted at some point after creation, property assignment is the way to go:
if (!this.MyApp) this.MyApp = ...(substitutingthiswithwindoworglobalas necessary) - Avoid mixing
this/window/globaland global variable object (used to create property during variable declaration); they could be different objects.
David Murdoch said on Mar 1, 2011 @ 11:26
#1IMO, the following is, in most cases, the right way to create a global object if
you don’t want to clobber a previous declaration.
// in global scope
(function(window, undefined){
if(window.MyApp === undefined){
window.MyApp = {};
}
}(this));
Also, there is some other misinformation in your post such as:
See?
var MyApp = 0;
alert(!MyApp); // true
alert(MyApp == null); // false
alert(MyApp == undefined); // false
Will Alexander said on Mar 1, 2011 @ 12:44
#2As usual, an extremely informative and exhaustive study!
As the previous comment pointed out, the false-y check may return a false-y positive. Is your goal to not override your previous declaration, or to not override any existing declaration. Clearly beyond the scope of this particular subject, but would love to know your opinion on how effective using MyApp as an object if its all ready declared as a different type.
Couple of minor typos:
From Patterns / #1, should the check be “==” ?
if (typeof MyApp != 'undefined') {Also minor, from Patterns / #12, should MyApp be in quotes?
if (!(MyApp in this)) {zcorpan said on Mar 2, 2011 @ 1:14
#3WindowProxy is not a non-requirement. It is required. Moreover, ‘this’ also references WindowProxy in HTML.
Kent Archie said on Mar 2, 2011 @ 12:32
#4Just got started (this looks fascinating) but I think there is a typo here
if (typeof MyApp != ‘undefined’) {
var MyApp = { };
}
Shouldn’t that be
if (typeof MyApp == ‘undefined’) {
var MyApp = { };
}
I look forward to reading the rest on the way home.
Benedikt said on Mar 3, 2011 @ 8:58
#5Nice article as always!
I recently wrote an asynchronous queue, inspired by google’s _gaq for analytics. I noticed something I see at least as a glitch, exactly what your talking about just with same file and external resource differences. Check the following example
// inlined, just to make visible
(function(queue){
if ('undefined'===typeof(window[queue])){
window[queue] = [];
}
q = window[queue];
q.push('outer');
}('_gaq'));
// main page code
var _gaq = _gaq || [];
_gaq.push('main');
alert(_gaq);
(the code is only part of my functionality in which I override the array’s push-function… the example is enough to demonstrate the problem.)
FF, Chrome and others will output “outer,main”, while IE6/7/8 will output just “main”
If you inline the external script.js above the main page code (or below, what the async queue is all about), it will work in IE also.
If you leave script.js external, but change “var _gaq = _gaq || [];” to “window._gaq = window._gaq || [];” it will work in IE also.
=> So I think it’s some kind of hoisting problem in IE with external resources.
In order to use my queue one now needs to use the attribute-declaration method in order to have my script.js working. I wonder how google managed to overcome that problem; unfortunatelly analytics.js is way to obfuscated to make any sense, even after jsbeautifier.org…
Any ideas why I am experiencing that? (propably jsut a minor syntax error?)
Benedikt said on Mar 4, 2011 @ 2:22
#6Since I made an error escaping my code, here is my example corrected and also a little bit changed: I noticed the same problem, when both scripts are external
index.html
<script type="text/javascript" src="script.js?r=”>
<script type="text/javascript" src="main.js?r=”>
alert(_gaq);
script.js
(function(queue){
if (‘undefined’===typeof(window[queue])){
window[queue] = [];
}
q = window[queue];
q.push(‘outer’);
}(‘_gaq’));
main.js
// window.gaq always works
//window._gaq = window._gaq || [];
// variable delcaration does not work in IE
var _gaq = _gaq || [];
_gaq.push(‘main’);
Yaffle said on Mar 7, 2011 @ 23:20
#8what aboute `self` property of global object(window or workerUtils implements it)?
if (!self.MyApp) {
self.MyApp = {};
}
Robert Green said on Mar 8, 2011 @ 16:47
#9Before evaluating which is best, you must first set out the criteria to be used for the evaluation.
For example, using a method that is supposedly suitable in ES3, ES5 and ES5-strict assumes that the related code is written for all of those environments. But why would someone write code for all 3 environments? What would be the point of using ES5 features if it was also necessary to write a fork for non-ES5 environments that (presumably) does exactly the same thing?
As for shaddowing of global variable, that can happen anytime. The only way you can stop it is to create a reference to the global object within a function scope and keep a closure to it. If you rely on any global properties, there is a chance one or more will be changed at some later time by code that is perhaps not under your control.
So establish the criteria first, then work out which is best for particular situations.
santhosh said on Mar 19, 2011 @ 23:50
#10it’s a great post.
I have a question here. As you said,
the second pattern,
if (!MyApp) {
var MyApp = { };
}
which is indirectly equals to
var MyApp;
if (!MyApp) {
MyApp = { };
}
but if i use undeclared assignment, then it will throw unreference error.
But, javascript is an interpreted language. As and when it encounters statment, it will execute. it won’t foresee the steps. Then what’s the difference if i use undeclared assignment or declared assignment.
with out foreseeing abilities, how declaring the variable in the next statement is working fine and undeclared assignment is causing error?
Robert Green said on Mar 20, 2011 @ 17:47
#11@santhosh
In your code it is not the assignment that causes the error, it’s the testing of an undeclared and uninitialised variable, i.e. this bit:
if (!MyApp) {
Note that in javascript (ECMAScript) execution has a variable instatiation phase that occurs before any code is executed. So declaring a variable anywhere makes it available when the code is run (so called “hoisting”). So you won’t get an error as long as MyApp is declared somewhere within the scope of the execution context it is being referenced from, or initialised earlier, e.g.
if (!MyApp) {
…
}
var MyApp;
or
MyApp = {};
if (!MyApp) {
…
}
Read Richard Cornford’s excellent article: http://www.jibbering.com/faq/notes/closures/#clExCon
Allowing assignment to undeclared variables is a special case, probably to make javascript forgiving.
santhosh said on Mar 20, 2011 @ 17:55
#12@Robert: thanks Robert.
Daniel Lopez said on Mar 20, 2011 @ 18:15
#13agreeing with David,
(function (global) {
if (oldModule === undefined) {
global.oldModule = {};
}
}(this));
Is the way to go, it’s amazing just how many different ways there are to do things in JS.
Jacob Rus said on Mar 25, 2011 @ 18:50
#14One that you missed is the use of
void 0instead ofundefined(e.g.if (MyApp === void 0) {…}). It avoids the problem ofundefinedbeing a writable property, and is a few characters shorter to boot.Garrett said on Jun 5, 2011 @ 0:07
#18The global object is not required to have a prototype — that’s implementation dependent. Using hasOwnProperty on global object will give surprising results in many versions of Opera. I don’t have Opera, but last I checked (over a year), `!hasOwnProperty.call(window, “Object”)` was true in Opera (I base this on an old code snippet of mine). IIRC, any declared property of global object in opera, hasOwnProperty.call(global, ‘any’), would result false.
Any namespace function must take this into account. I ended up dealing with it with something like: `if(this === window) return (p in this) && (Object.prototype[p] !== this[p]);`
Opera’s behavior might be explained by `WindowProxy` which you brought up (my guess).
Gajus Kuizinas said on Jun 5, 2011 @ 10:46
#19Small typo.
globa.MyApp = { };in #7. Perfect reading.Julián Landerreche said on Sep 7, 2011 @ 9:45
#25But a local variable in the global scope isn’t just a property in the global scope (i.e. a global property)?
I mean, in the console, I’ve tested
Foo = "a"
var Foo = "b"
this.Foo // prints "b"
What am I missing?
Julián Landerreche said on Sep 7, 2011 @ 9:46
#26Ops! Not sure what happened with my comment, but it looks a bit mangled (seems a CSS issue with floats).
Troy III said on Oct 10, 2011 @ 0:28
#28Foo = “a”
var Foo = “b”
this.Foo // prints “b”
Are both global whenever “Foo” is defined in a global scope.
The difference is declared vs undeclared. Which is very useful.
My advice is:
1. Never use declared variables in a global scope, it’s a bad restricting practice and a persistent pollution.
2. Allways use declared variables in local scope.
3. Use with confidence all undeclared vars in local scope whenever the global access is required.
The value and the beauty of undeclared variables, much later…
schools environmental said on Sep 19, 2012 @ 23:01
#51Amazing! Its truly remarkable article, I have got much clear idea about from
this article.
How to cheat candy crush said on May 19, 2013 @ 11:41
#54My coder is trying to convince me to move to .net from PHP.
I have always disliked the idea because of the expenses.
But he’s tryiong none the less. I’ve been using Movable-type on a number of websites for about a year and am concerned about switching to another platform.
I have heard great things about blogengine.
net. Is there a way I can transfer all my wordpress content into it?
Any kind of help would be greatly appreciated!