Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

var x = x || "default val" not getting set properly if x is defined above it

HTML:

<script type="text/javascript">
  var x = "overriden";
</script>
<script src="myjs.js"></script>

myjs.js:

$(document).ready(function(){
  var x = x || "default val";
  alert(x); // this alerts "default val" and not "overriden"
});

For some reason, x is ending up as "default val" and not "overriden", even tho initially I'm setting it to "overriden" before I even include the script reference to myjs.js.

Any idea as to why this is happening? I'm trying to enable the hosting page to set an override for a variable that's used in an included js file, otherwise use the default val.

like image 302
Ian Davis Avatar asked Jan 19 '12 20:01

Ian Davis


People also ask

What does X || Y mean?

Now, when you know how || operator works, you can probably make out by yourself what does x = x || y mean. If x is truthy, x is assigned to x , so actually nothing happens; otherwise y is assigned to x . It is commonly used to define default parameters in functions.

What happens if you omit var when defining a variable inside a function or method?

Variables can be declared and initialize without the var keyword. However, a value must be assigned to a variable declared without the var keyword. The variables declared without the var keyword becomes global variables, irrespective of where they are declared.

How do you check if an element is defined in JavaScript?

The typeof operator will check whether a variable is defined or not. The typeof operator doesn't throw a ReferenceError exception when it is used with an undeclared variable. The typeof null will return an object.

What is var {} in JS?

The var statement declares a variable. Variables are containers for storing information. Creating a variable in JavaScript is called "declaring" a variable: var carName; After the declaration, the variable is empty (it has no value).


1 Answers

What you have after variable declaration hoisting is applied:

var x;
x = 5;

$(document).ready(function(){
    var x;
    x = x || "default";
});

It looks at the closest x and sees it's value is undefined which is a falsy value, so x gets set to "default".


You would be fine if they were in the same scope, because the declarations are always hoisted above assignments so:
var x = 5;

var x = x || "default";

Is actually just

var x;

x = 5;
x = x || "default";

This was suggested which is completely pointless:

$(document).ready(function(){
    x = x || "default";
});

It will throw a ReferenceError if x is not defined.


So either do the check in the same scope or do something like:
$(document).ready(function(){
    var x = window.x || "default";
});

Invalid property reads don't cause a ReferenceError but just return undefined instead.

like image 186
Esailija Avatar answered Jan 04 '23 12:01

Esailija