Reputation: 3388
The book JavaScript for PHP Developers contains the following commented code (to which I've added alert()s to display the values of single-variable-expression statements of the form
variable;
and to which I have also added the 'use strict' directive to see if that was what was causing the problem. I cannot reproduce the code on JSFiddle with Firefox. I've added my own comments to the code in large caps:
'use strict';
// Create a global variable
var john = "Jo";
alert(john); // "Jo"
alert(window.john); // "Jo", works as a property too
/* BUT I GET UNDEFINED HERE */
// Create a property of the global object
window.jane = "JJ";
alert(jane); // "JJ", works as a variable too
alert(window.jane); // "JJ"
// Delete them
alert(delete window.john); // false
/* BUT I GET true HERE */
alert(delete window.jane); // true
alert(john); // "Jo"
alert(jane); // undefined
/* BUT PROGRAM CRASHES HERE */
alert(this === window); // true
In fact in the following small program the last alert function call is never reached:
window.jane = "JJ";
delete window.jane;
alert(jane); // Program Crashes
alert('Got Here');
I've tested all cases one more time here which illustrates all cases.
var a = 'John';
window.b = 'Jane';
c = 'Jack';
alert(a); // John
alert(b); // Jane
alert(c); // Jack
alert(window.a); // undefined
alert(window.b); // Jane
alert(window.c); // Jack
alert(delete a); // false
alert(delete b); // true
alert(delete c); // true
alert(a); // John
//alert(b); // would crash
//alert(c); // would crash
window.b = 'Jane';
c = 'Jack';
alert(delete window.a); // true
alert(delete window.b); // true
alert(delete window.c); // true
alert(window.a); // undefined
alert(window.b); // undefined
alert(window.c); // undefined
alert(a); // John
//alert(b); // would crash
//alert(c); // would crash
What I want to know is, is this behavior consistent across all browsers or are differences between one browser and another. Is the code from the book a mistake or was it simply run against a different browser than my own (Firefox 33.0.1)?
If someone could explain the various cases, perhaps pointing to the relevant sections of the ECMA specification, it would be greatly appreciated.
Thanks.
OK, the results I am seeing are such because I have run the code in JSFiddle inside the onload function and not at the global scope, as pointed out. Here is the result of running the comprehensive test inside a web page served from my local machine. The results on JSFiddle with the script inside the body html element are the same:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
var a = 'John';
window.b = 'Jane';
c = 'Jack';
alert(a); // John
alert(b); // Jane
alert(c); // Jack
alert(window.a); // John
alert(window.b); // Jane
alert(window.c); // Jack
alert(delete a); // false
alert(delete b); // true
alert(delete c); // true
alert(a); // John
try { alert(b); } catch (e) { alert(e); } // throws ReferenceError: b is not defined
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined
window.b = 'Jane';
c = 'Jack';
alert(delete window.a); // false
alert(delete window.b); // true
alert(delete window.c); // true
alert(window.a); // John
alert(window.b); // undefined
alert(window.c); // undefined
alert(a); // John
try { alert(b); } catch (e) { alert(e); } // throws ReferenceError: b is not defined
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined
</script>
</body>
</html>
and here is what happens when the ECMAScript5 'use strict' directive is also used. While I'm aware that declaring a variable without var in strict mode causes a reference error I'm not sure I can make sense of the rest of the output, in particular why does script execution terminate at certain places:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript">
'use strict';
var a = 'John';
window.b = 'Jane';
try { c = 'Jack'; } catch (e) { alert(e); } // throws ReferenceError: assignment to undeclared variable c
alert(a); // John
alert(b); // Jane
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined
alert(window.a); // John
alert(window.b); // Jane
alert(window.c); // undefined
try {
// Uncommenting any of these three following statements will cause the script to be exited
// during the parsing time; no statement from this script will be executed.
//alert(delete a); causes script to end during parsing at runtime even though try catch block present
//alert(delete b); causes script to end during parsing at runtime even though try catch block present
//alert(delete c); causes script to end during parsing at runtime even though try catch block present
} catch (e) { alert(e); }
alert(a); // John
try { alert(b); } catch (e) { alert(e); } // Jane
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined
window.b = 'Jane';
c = 'Jack';
try {
//alert(delete window.a); // causes script to end during execution at runtime even though try catch block present
//alert(delete window.b); // causes script to end during execution at runtime even though try catch block present
//alert(delete window.c); // causes script to end during execution at runtime even though try catch block present
} catch (e) { alert(e); }
/* Script stops execution at this point. Why?????
alert(window.a); //
alert(window.b); //
alert(window.c); //
alert(a); //
try { alert(b); } catch (e) { alert(e); } //
try { alert(c); } catch (e) { alert(e); } //
</script>
</body>
</html>
If anyone can help me interpreting why the script executions terminate in some places the way they do with strict mode it would be greatly appreciated.
Thanks.
With regards to the origninal code from the book, when run properly from within a script
tag in the head of the document, I get the following output, were we can see that a
ReferenceError instance due to accessing variable jane
is thrown.
Here is the JSFiddle for the code:
//'use strict'
// Create a global variable
var john = "Jo";
alert(john); // "Jo"
alert(window.john); // "Jo", works as a property too
// Create a property of the global object
window.jane = "JJ";
alert(jane); // "JJ", works as a variable too
alert(window.jane); // "JJ"
// Delete them
try { alert(delete window.john); } catch (e) { alert(e); }
// false
/* if strict mode were enforced would actually cause
the following fatal error:
TypeError:
property "john" is non-configurable and can't be deleted
*/
try { alert(delete window.jane); } catch (e) { alert(e); }
// true
alert(john); // "Jo"
try { alert(jane); } catch (e) { alert(e); } // undefined in book
/* but actually gives a:
ReferenceError: jane is not defined
which is a fatal error causing the script to exit
if not caught*/
alert(this === window); // true
Upvotes: 0
Views: 66
Reputation: 413757
Look at this part of the interface to jsfiddle:
That "onLoad" selector means that the code you type into the JavaScript quadrant of the interface will be wrapped in a function for you, and that that function will serve as the "load" event handler for the window. Because your code is in a function, variables you declare at what appears to be the global level really aren't global; they're local variables in the function.
To make your code truly global, change that selection to one of the "no wrap" settings.
Upvotes: 1