0

Running play framework version 2.3, though it may not be relevant:

I have an html file with the following contents:

<html>
    <head>
        <script type="text/javascript"> if (typeof x === 'undefined') {console.log("x not defined");} else {console.log("in html, x is %s", typeof x);} </script>
        <script type="text/javascript" src="javascripts/somescript.js"></script>
    </head>
</html>

and somescript.js has this:

(function() {
    jQuery(function() {
        if (typeof x === 'undefined') {
            console.log("in somescript.js, x is %s", typeof x);
            var x = something;
            //other stuff
        }
    });
}).call(this);

When I load page first time, x is undefined as expected. However, when I go to a different page within same application, and then come back, the console reads:

in html, x is object
in somescript.js, x is undefined

This is weird because in html, if statement is false, but in somescript.js, same if statement is true.

Why is it doing this, and how can I make sure both scripts run in same way?

  • Each is testing a different `x` variable from a different scope. Note that the declaration of `var x` in somescript.js is [hoisted](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) to the top of the `function`, above the `if`. And, it's possible something else you aren't showing here is defining a global `x`. – Jonathan Lonowski Jul 03 '14 at 17:06
  • @JonathanLonowski good catch. At somescript.js's `if`, `x` is always undefined as its declaration is hoisted and [shadows](http://en.wikipedia.org/wiki/Variable_shadowing) the global `x`. – Fabrício Matté Jul 03 '14 at 17:08
  • Possible duplicate of [variable hoisting](http://stackoverflow.com/questions/3725546/variable-hoisting). Also related [JavaScript 'hoisting'](http://stackoverflow.com/questions/15311158/javascript-hoisting) – Jonathan Lonowski Jul 03 '14 at 17:14

1 Answers1

1

This is variable hoisting - if you declare a variable anywhere inside a function, it's definition gets hoisted to the top.

x = 0;
function y() {
    //var x; you don't write it here, but internally this is happening
    if (typeof x === 'undefined') {
        alert('x is undefined');
        var x = 1; //because you use var, you are declaring a new variable x,
                   //so it gets hoisted to the top
    }
}
y(); //alerts x is undefined

But if you do:

x = 0;
function y() {
    if (typeof x === 'undefined') {
        alert('x is undefined');
        x = 1; //we don't use var, so we aren't redeclaring it, just setting its value
    }
}
y(); //nothing happens
dave
  • 62,300
  • 5
  • 72
  • 93