John Sonderson
John Sonderson

Reputation: 3388

'JavaScript for PHP Developers -> The Built-In API -> The Global Object': cannot reproduce code in browser

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

Answers (1)

Pointy
Pointy

Reputation: 413757

Look at this part of the interface to jsfiddle:

jsfiddle screenshot

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

Related Questions