Global JSON variable override
javascript, json, scope
Solution
For each variable declaration (not initialization!). The following happens (section `#10.5`):
8. For each VariableDeclaration and VariableDeclarationNoIn d in code, in source text order do
- Let dn be the Identifier in d.
- Let varAlreadyDeclared be the result of calling env’s HasBinding concrete method passing dn as the argument.
- If varAlreadyDeclared is false, then
- Call env’s CreateMutableBinding concrete method passing dn and configurableBindings as the arguments.
- Call env’s SetMutableBinding concrete method passing dn, undefined, and strict as the arguments.
So you see, whenever `var x` is encountered, it is tested whether a variable with name `x` already exists in the environment. If yes, it is just ignored, but if not, then the variable is declared and initialized with `undefined`.
Since the code is run in global scope it tests whether `JSON` exists in global scope. So if `JSON` already exists, `var JSON;` is just ignored.
Just some thoughts regarding testing/explaining this behaviour:
I don't know at which point in the JavaScript execution the global object is created, but I assume before all other scripts are evaluated. That means, `JSON` exists and has a value before any variable declaration, something you can only simulate if you include two scripts (can also be inline I guess, they are evaluated after another).
Try:
// script1.js
var foo = 'bar';
// script2.js
var foo;
if(!foo) {
foo = 'baz';
}
alert(foo);
// include script2.js after script1.js
What's the result? (cheaters look here).
Whenever you are in a single script file, all variable declarations are hoisted to the top anyways. So if you have
var foo = 'bar';
var foo;
if(!foo) {
foo = 'baz';
}
the script is actually executed as:
var foo;
var foo;
foo = 'bar';
if(!foo) {
foo = 'baz';
}
You could not actually test whether the second `var foo;` overwrites the first one, since at this point it has no value yet. So this is not a good example to demonstrate the behaviour quoted above.
Problem
I had to use json2.js in my project as browser(IE8) JSON object was not available for parsing strings to JSON. I ran through json2.js and am having a doubt with the variable declaration. A JSON global variable is declared in json2.js like ``` var JSON; if(!JSON){ JSON={}; } ``` What is the effect of declaration `var JSON;` on the global JSON object. I hope the declaration should override the global JSON object in any browser (IE8/IE7). But for my surprise it is not overriding when a global object is available. Only a variable definition / initiation overrides a global variable? Kindly clarify.