Is this a variable definition or declaration? And why?
var x;
..and is the memory reserved for x after this statement?
EDIT:
In C extern int x; is a declaration, int x = 5; is a definition. What's the analog in JS? Wikipedia says a declaration allocates memory and the definition assigns a value to this allocated memory.
SECOND EDIT:
I think the explanation of #Deryck sounds great, but there's some output that disagrees with his explanation:
> var x;
undefined
> x
undefined // now it looks like x is defined to the value undefined
> y
ReferenceError: y is not defined
If the ReferenceError output would say y is not declared it would make sense. But often I read that JS has two non-values: null and undefined. So var x would be a definition with the value undefined.
var x is a declaration because you are not defining what value it holds but you are declaring its existence and the need for memory allocation.
var x = 1 is both declaration and definition but are separated with x being declared in the beginning while its definition comes at the line specified (variable assignments happen inline).
I see that you already understand the concept of hoisting but for those that don't, Javascript takes every variable and function declaration and brings it to the top (of its corresponding scope) then trickles down assigning them in order.
You seem to know most of this already though. Here's a great resource if you want some advanced, in-depth exploration. Yet I have a feeling you've been there before.
Javascript Garden
PS - your analogy between C variable dec/def and JS was spot on. What you read on Wikipedia was correct.
Declaring a variable is like telling the (javascript) compiler that this token x is something I want to use later. It does point to a location in memory, but it does not yet contain a value. ie. it is undefined
var x;
defining it means to give it a value which you can either do it like:
x = 10; // defining a variable that was declared previously
or like this:
var y = 20; // declaring and defining a variable altogether.
http://msdn.microsoft.com/en-us/library/67defydd(v=vs.94).aspx
http://www.w3schools.com/js/js_variables.asp
I will give you a long answer for better explanation.
When the javascript engine is not able to find a particular variable in memory, it will throw an error. To be more specific, when the javascript engine (Execution Context) is not able to "reference" a variable in memory, it will throw a ReferenceError. This is not exactly the same as a Declaration Error, at least in javascript.
There is a deference between a not defined error and the value undefined.
So doing
var a = undefined;
and
var a;
will both log the same result i.e. undefined. This is because, when you simply do a var a; the javascript engine allocates memory for the variable and automatically sets it's value to undefined, which is different from saying that a doesn't exist at all - in which case it will throw a ReferenceError.
Hoisting
console.log(a); // undefined
var a = 'something';
will log undefined because, the javascript engine knows there's a variable declared somewhere in the code - which means to say that the javascript engine actually does something before it executes the code - one of the thing it does is hoists variables. To put it simply, the above code is the same as
var a; // hoisted (declared and defined the value `undefined`)
console.log(a); // undefined
a = 'something' // update the defined value to `something`
So, yes, declaration and definition happen together in javascript (automatically - if you don't do it yourself) and the default defined value is undefined.
ES6
Just an additional note
const a;
will throw a SyntaxError where a initializer (definition) is necessary. const is the only time when you need to declare and define manually.
> var x;
undefined
> x
undefined // now it looks like x is defined to the value undefined
> y
ReferenceError: y is not defined
Although it is usually said that Javascript is an interpreted language, but there is also a compilation step that happens very fast just before the interpreter runs. The job of this compilation step is to create scope chains, where variables are declared(no read/write operation here, just simple name-keeping) in their respective scopes. These variables will point to some memory location but value in it will be undefined until some execution is carried out by the interpreter.
> Compiler run:
When compiler sees var x;, it will simply book-keep this variable in its respective scope.
The next x; and y; are simply ignored in the compilation step as they are execution statements.
> Interpreter run:
When interpreter sees var x;, it will skip this as there is no read/write operation here.
Now when interpreter sees x;(execution statement), "x" will already be declared in the scope, and it will hold value "undefined", which is what you get on the console.
But when interpreter sees y; similarly, there has been no previous declaration or name-keeping for it in the compilation step, and thus we get the ReferenceError as expected.
Hope someone finds this comment useful.
var x, y, z;
var x;
var h = 4;
i = 4;
all the above are global variables if placed at the top, (outside any functions)
Lets say that the javascript has a function start
function start() {
x = 5*5;
}
the global variable x is now equal to 25
Where as if the var x; was not placed outside of any functions, that variable x would just be local to that function.
You declare JavaScript variables with the var keyword:
var carname;
After the declaration, the variable is empty (it has no value).
To assign a value to the variable, use the equal sign
var carname="Volvo";
In computer programs, variables are often declared without a value. The value can be something that has to be calculated, or something that will be provided later, like user input. Variable declared without a value will have the value undefined.
The variable carname will have the value undefined after the execution of the following statement:
var carname;
var hoisting
In JavaScript, a variable can be declared after being used.
bla = 2
var bla;
// ...
// is implicitly understood as:
var bla;
bla = 2;
For that reason, it is recommended to always declare variable at the top of functions. Otherwise, it may lead to confusing cases
When declaring a variable without assigning a value to it, there still needs to be some memory available for it, otherwise you cannot make a reference to the variable later in the program. I don't think it's a noticeable amount of memory being used and won't make a difference.
var x;
This is a variable declaration. In Js if you don't assign any value to variable in declaration. It will get undefined by default.
var x; // declaring x
console.log(x); // output: undefined
But if you have not even declared the variable in you try to access it. It says that the variable is not defined.
console.log(y); // Output: ReferenceError: y is not defined
If you need access to objects between JS files, it's good practice to expose one object to the global namespace and declare fields and methods on that object.
File 1:
var myObject;
myObject.myField = "Field!";
File 2:
myObject.prototype.myFunction = function () {
return this.myField;
};
I have taken from a really good discussion on : Equivalent of C extern declaration in JavaScript
https://github.com/ganqqwerty/123-Essential-JavaScript-Interview-Questions
Various trivia regarding the difference between undefined and null completely aside, the short answer is: there is no equivalence in Javascript. There are no bare "forward declarations". Javascript variable declarations are definitions. Variables that have been defined but not explicitly initialized will contain the value 'undefined'. There is no "external linkage".
If you refer to an identifier that is not in any accessible scope (perhaps because it doesn't exist the first place), you will get your "ReferenceError: y is not defined". This has nothing to do with variable value or storage.
In simple terms,
undefined means value to the variable is not defined.
not defined means the variable itself is not defined.
var x; //value is not defined. So,
x //undefined
//y variable is not declared or defined. So,
y // y is not defined
Related
I'm learning JS by reading a book (Learning JavaScript by Ethan Brown) where author writes:
Lexical scoping means whatever variables are in scope where you define
a function from (as opposed to when you call it) are in scope in the
function. Consider this example:
const x = 3;
function f() {
console.log(x); // this will work
console.log(y); // this will cause a crash
}
const y = 3;
f();
The variable x exists when we define the function f , but y doesn’t.
Then we declare y and call f , and see that x is in scope inside the
body of f when it’s called, but y isn’t. This is an example of lexical
scoping: the function f has access to the identifiers that
were available when it was defined, not when it was called
When I run it in VS Code debugger, there doesn't seem to be any errors.
I see
3
3
without any exceptions. Can this depend on ES version that I'm using or something else?
Though I think the author simply chose a poor (well, incorrect) piece of code to illustrate the point, the code is interesting as a way to illustrate something related but different. Because y is declared with const, it is visible inside the function because its declaration is hoisted to the nearest enclosing block (which is not explicitly visible in the posted code, but it must be there somewhere). However, if the function call is moved to before that declaration, you will see an error because the reference to y will happen in the somewhat weirdly-named "temporal dead zone". References to declared but uninitialized variables created with let or const are runtime errors.
If the declaration of y is changed to a var declaration, then moving the function call to before variable declaration does not cause an error because the variable is defined and in scope but is simply (old-school) uninitialized, and therefore simply undefined.
This works because const y=3 is declared before f() is called. If you move the declaration of y after f() then it will work as "expected"
This is a serious question, It has been nagging me for a while. In JavaScript you can declare a variable which has no type. It's type is often dynamic, depends on further value assigned to it.
e.g
var text;
typeof(text); //undefined
text = 'someText';
typeof(text); //string
So as we know that Javascript can dynamically change variable's type why these assignments are invalid then?
e.g
var someObj;
someObj.a = 'hello world';
console.log(someObj) //TypeError
var someTable;
someTable[0] = 'hello world';
console.log(someTable[0]) //TypeError
where this problem can be fixed just by adding definition to variable declaration:
var someObj = {};
var someTable = [];
I'd expect a good explanation of this problem. Thanks for answers.
There's a big difference between declaration and initialisation of variables.
When you declare a variable without initializing it with a value, its type will be undefined, so when you will try to call it or access it, it will give undefined, because simply there were no value defined for the variable.
That's why it should be initialized:
var someObj = {};
var someTable = [];
So you can treat it as a string, an object or an array according its initialized value.
Documentation:
Please take a look at variables MDN Reference for further reading, where it says:
A var statement declares variables that are scoped to the running execution context’s VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. [...] A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.
You're getting confused about where the error is thrown. In your first example:
var someObj;
someObj.a = 'hello world'; // the error is thrown here
That error is thrown because someObj is undefined (not undeclared). So, you can't access the property a on undefined.
The same explanation applies for your second example:
var someTable;
someTable[0] = 'hello world'; // the error is thrown here
You're trying to access index 0 of undefined.
The reason that defining them as {} and [], respectively, fixes your issue, is that you are then accessing property a of {} and index 0 of [].
1) Data types in Javascript are not dynamic, they are mutable. This means that depending on kind of operation you are applying to them they can change from being something into another thing (e.g. a number can become a string doing something like this: 4 + 'a').
2) The "error" is a consequence of having a variable not initialized. In Javascript when you are doing this:var something = 'a'
you are doing two operations, a declaration, and an assignment. If you don't do the assignment and you try to access to a property of the object you have declared it will throw an error. In your case, you are declaring a variable but not initializing it to the "compiler" can't access the "a" property or the position 1 because it is of type undefined.
Today, I got completely surprised when I saw that a global variable has undefined value in a certain case.
Example:
var value = 10;
function test() {
//A
console.log(value);
var value = 20;
//B
console.log(value);
}
test();
Gives output as
undefined
20
Here, why is the JavaScript engine considering global value as undefined? I know that JavaScript is an interpreted language. How is it able to consider variables in the function?
Is that a pitfall from the JavaScript engine?
This phenomenon is known as: JavaScript Variable Hoisting.
At no point are you accessing the global variable in your function; you're only ever accessing the local value variable.
Your code is equivalent to the following:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
Still surprised you're getting undefined?
Explanation:
This is something that every JavaScript programmer bumps into sooner or later. Simply put, whatever variables you declare are always hoisted to the top of your local closure. So, even though you declared your variable after the first console.log call, it's still considered as if you had declared it before that.
However, only the declaration part is being hoisted; the assignment, on the other hand, is not.
So, when you first called console.log(value), you were referencing your locally declared variable, which has got nothing assigned to it yet; hence undefined.
Here's another example:
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
What do you think this will alert? No, don't just read on, think about it. What's the value of test?
If you said anything other than start, you were wrong. The above code is equivalent to this:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
so that the global variable is never affected.
As you can see, no matter where you put your variable declaration, it is always hoisted to the top of your local closure.
Side note:
This also applies to functions.
Consider this piece of code:
test("Won't work!");
test = function(text) { alert(text); }
which will give you a reference error:
Uncaught ReferenceError: test is not defined
This throws off a lot of developers, since this piece of code works fine:
test("Works!");
function test(text) { alert(text); }
The reason for this, as stated, is because the assignment part is not hoisted. So in the first example, when test("Won't work!") was run, the test variable has already been declared, but has yet to have the function assigned to it.
In the second example, we're not using variable assignment. Rather, we're using proper function declaration syntax, which does get the function completely hoisted.
Ben Cherry has written an excellent article on this, appropriately titled JavaScript Scoping and Hoisting.
Read it. It'll give you the whole picture in full detail.
I was somewhat disappointed that the problem here is explained, but no one proposed a solution. If you want to access a global variable in function scope without the function making an undefined local var first, reference the var as window.varName
Variables in JavaScript always have function-wide scope. Even if they were defined in the middle of the function, they are visible before. Similar phenomena may be observed with function hoisting.
That being said, the first console.log(value) sees the value variable (the inner one which shadows the outer value), but it has not yet been initialized. You can think of it as if all variable declarations were implicitly moved to the beginning of the function (not inner-most code block), while the definitions are left on the same place.
See also
Javascript function scoping and hoisting
Javascript variable declarations at the head of a function
There is a global variable value, but when control enters the test function, another value variable is declared, which shadows the global one. Since variable declarations (but not assignments) in JavaScript are hoisted to the top of scope in which they are declared:
//value == undefined (global)
var value = 10;
//value == 10 (global)
function test() {
//value == undefined (local)
var value = 20;
//value == 20 (local)
}
//value == 10 (global)
Note that the same is true of function declarations, which means you can call a function before it appears to be defined in your code:
test(); //Call the function before it appears in the source
function test() {
//Do stuff
}
It's also worth noting that when you combine the two into a function expression, the variable will be undefined until the assignment takes place, so you can't call the function until that happens:
var test = function() {
//Do stuff
};
test(); //Have to call the function after the assignment
The simplest way to keep access to outer variables (not just of global scope) is, of course, to try to not re-declare them under the same name in functions; just do not use var there. The use of proper descriptive naming rules is advised. With those, it will be hard to end up with variables named like value (this aspect is not necessarily related to the example in the question as this variable name might have been given for simplicity).
If the function might be reused elsewhere and hence there is no guarantee that the outer variable actually defined in that new context, Eval function can be used. It is slow in this operation so it is not recommended for performance-demanding functions:
if (typeof variable === "undefined")
{
eval("var variable = 'Some value';");
}
If the outer scope variable you want access to is defined in a named function, then it might be attached to the function itself in the first place and then accessed from anywhere in the code -- be it from deeply nested functions or event handlers outside of everything else. Notice that accessing properties is way slower and would require you to change the way you program, so it is not recommended unless it is really necessary: Variables as properties of functions (JSFiddle):
// (the wrapper-binder is only necessary for using variables-properties
// via "this"instead of the function's name)
var functionAsImplicitObjectBody = function()
{
function someNestedFunction()
{
var redefinableVariable = "redefinableVariable's value from someNestedFunction";
console.log('--> functionAsImplicitObjectBody.variableAsProperty: ', functionAsImplicitObjectBody.variableAsProperty);
console.log('--> redefinableVariable: ', redefinableVariable);
}
var redefinableVariable = "redefinableVariable's value from someFunctionBody";
console.log('this.variableAsProperty: ', this.variableAsProperty);
console.log('functionAsImplicitObjectBody.variableAsProperty: ', functionAsImplicitObjectBody.variableAsProperty);
console.log('redefinableVariable: ', redefinableVariable);
someNestedFunction();
},
functionAsImplicitObject = functionAsImplicitObjectBody.bind(functionAsImplicitObjectBody);
functionAsImplicitObjectBody.variableAsProperty = "variableAsProperty's value, set at time stamp: " + (new Date()).getTime();
functionAsImplicitObject();
// (spread-like operator "..." provides passing of any number of arguments to
// the target internal "func" function in as many steps as necessary)
var functionAsExplicitObject = function(...arguments)
{
var functionAsExplicitObjectBody = {
variableAsProperty: "variableAsProperty's value",
func: function(argument1, argument2)
{
function someNestedFunction()
{
console.log('--> functionAsExplicitObjectBody.variableAsProperty: ',
functionAsExplicitObjectBody.variableAsProperty);
}
console.log("argument1: ", argument1);
console.log("argument2: ", argument2);
console.log("this.variableAsProperty: ", this.variableAsProperty);
someNestedFunction();
}
};
return functionAsExplicitObjectBody.func(...arguments);
};
functionAsExplicitObject("argument1's value", "argument2's value");
I was running into the same problem even with global variables. My problem, I discovered, was global variable do Not persist between html files.
<script>
window.myVar = 'foo';
window.myVarTwo = 'bar';
</script>
<object type="text/html" data="/myDataSource.html"></object>
I tried to reference myVar and myVarTwo in the loaded HTML file, but received the undefined error.
Long story/day short, I discovered I could reference the variables using:
<!DOCTYPE html>
<html lang="en">
<!! other stuff here !!>
<script>
var myHTMLVar = this.parent.myVar
/* other stuff here */
</script>
</html>
Today, I got completely surprised when I saw that a global variable has undefined value in a certain case.
Example:
var value = 10;
function test() {
//A
console.log(value);
var value = 20;
//B
console.log(value);
}
test();
Gives output as
undefined
20
Here, why is the JavaScript engine considering global value as undefined? I know that JavaScript is an interpreted language. How is it able to consider variables in the function?
Is that a pitfall from the JavaScript engine?
This phenomenon is known as: JavaScript Variable Hoisting.
At no point are you accessing the global variable in your function; you're only ever accessing the local value variable.
Your code is equivalent to the following:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
Still surprised you're getting undefined?
Explanation:
This is something that every JavaScript programmer bumps into sooner or later. Simply put, whatever variables you declare are always hoisted to the top of your local closure. So, even though you declared your variable after the first console.log call, it's still considered as if you had declared it before that.
However, only the declaration part is being hoisted; the assignment, on the other hand, is not.
So, when you first called console.log(value), you were referencing your locally declared variable, which has got nothing assigned to it yet; hence undefined.
Here's another example:
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
What do you think this will alert? No, don't just read on, think about it. What's the value of test?
If you said anything other than start, you were wrong. The above code is equivalent to this:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
so that the global variable is never affected.
As you can see, no matter where you put your variable declaration, it is always hoisted to the top of your local closure.
Side note:
This also applies to functions.
Consider this piece of code:
test("Won't work!");
test = function(text) { alert(text); }
which will give you a reference error:
Uncaught ReferenceError: test is not defined
This throws off a lot of developers, since this piece of code works fine:
test("Works!");
function test(text) { alert(text); }
The reason for this, as stated, is because the assignment part is not hoisted. So in the first example, when test("Won't work!") was run, the test variable has already been declared, but has yet to have the function assigned to it.
In the second example, we're not using variable assignment. Rather, we're using proper function declaration syntax, which does get the function completely hoisted.
Ben Cherry has written an excellent article on this, appropriately titled JavaScript Scoping and Hoisting.
Read it. It'll give you the whole picture in full detail.
I was somewhat disappointed that the problem here is explained, but no one proposed a solution. If you want to access a global variable in function scope without the function making an undefined local var first, reference the var as window.varName
Variables in JavaScript always have function-wide scope. Even if they were defined in the middle of the function, they are visible before. Similar phenomena may be observed with function hoisting.
That being said, the first console.log(value) sees the value variable (the inner one which shadows the outer value), but it has not yet been initialized. You can think of it as if all variable declarations were implicitly moved to the beginning of the function (not inner-most code block), while the definitions are left on the same place.
See also
Javascript function scoping and hoisting
Javascript variable declarations at the head of a function
There is a global variable value, but when control enters the test function, another value variable is declared, which shadows the global one. Since variable declarations (but not assignments) in JavaScript are hoisted to the top of scope in which they are declared:
//value == undefined (global)
var value = 10;
//value == 10 (global)
function test() {
//value == undefined (local)
var value = 20;
//value == 20 (local)
}
//value == 10 (global)
Note that the same is true of function declarations, which means you can call a function before it appears to be defined in your code:
test(); //Call the function before it appears in the source
function test() {
//Do stuff
}
It's also worth noting that when you combine the two into a function expression, the variable will be undefined until the assignment takes place, so you can't call the function until that happens:
var test = function() {
//Do stuff
};
test(); //Have to call the function after the assignment
The simplest way to keep access to outer variables (not just of global scope) is, of course, to try to not re-declare them under the same name in functions; just do not use var there. The use of proper descriptive naming rules is advised. With those, it will be hard to end up with variables named like value (this aspect is not necessarily related to the example in the question as this variable name might have been given for simplicity).
If the function might be reused elsewhere and hence there is no guarantee that the outer variable actually defined in that new context, Eval function can be used. It is slow in this operation so it is not recommended for performance-demanding functions:
if (typeof variable === "undefined")
{
eval("var variable = 'Some value';");
}
If the outer scope variable you want access to is defined in a named function, then it might be attached to the function itself in the first place and then accessed from anywhere in the code -- be it from deeply nested functions or event handlers outside of everything else. Notice that accessing properties is way slower and would require you to change the way you program, so it is not recommended unless it is really necessary: Variables as properties of functions (JSFiddle):
// (the wrapper-binder is only necessary for using variables-properties
// via "this"instead of the function's name)
var functionAsImplicitObjectBody = function()
{
function someNestedFunction()
{
var redefinableVariable = "redefinableVariable's value from someNestedFunction";
console.log('--> functionAsImplicitObjectBody.variableAsProperty: ', functionAsImplicitObjectBody.variableAsProperty);
console.log('--> redefinableVariable: ', redefinableVariable);
}
var redefinableVariable = "redefinableVariable's value from someFunctionBody";
console.log('this.variableAsProperty: ', this.variableAsProperty);
console.log('functionAsImplicitObjectBody.variableAsProperty: ', functionAsImplicitObjectBody.variableAsProperty);
console.log('redefinableVariable: ', redefinableVariable);
someNestedFunction();
},
functionAsImplicitObject = functionAsImplicitObjectBody.bind(functionAsImplicitObjectBody);
functionAsImplicitObjectBody.variableAsProperty = "variableAsProperty's value, set at time stamp: " + (new Date()).getTime();
functionAsImplicitObject();
// (spread-like operator "..." provides passing of any number of arguments to
// the target internal "func" function in as many steps as necessary)
var functionAsExplicitObject = function(...arguments)
{
var functionAsExplicitObjectBody = {
variableAsProperty: "variableAsProperty's value",
func: function(argument1, argument2)
{
function someNestedFunction()
{
console.log('--> functionAsExplicitObjectBody.variableAsProperty: ',
functionAsExplicitObjectBody.variableAsProperty);
}
console.log("argument1: ", argument1);
console.log("argument2: ", argument2);
console.log("this.variableAsProperty: ", this.variableAsProperty);
someNestedFunction();
}
};
return functionAsExplicitObjectBody.func(...arguments);
};
functionAsExplicitObject("argument1's value", "argument2's value");
I was running into the same problem even with global variables. My problem, I discovered, was global variable do Not persist between html files.
<script>
window.myVar = 'foo';
window.myVarTwo = 'bar';
</script>
<object type="text/html" data="/myDataSource.html"></object>
I tried to reference myVar and myVarTwo in the loaded HTML file, but received the undefined error.
Long story/day short, I discovered I could reference the variables using:
<!DOCTYPE html>
<html lang="en">
<!! other stuff here !!>
<script>
var myHTMLVar = this.parent.myVar
/* other stuff here */
</script>
</html>
Just now,I saw some code like this:
if(condition){
var xx='sss';
}
//do something
if(condition){
console.info(xx);
}
Now, I just wonder why the second if statement work? How can it access the xx variable since it is a local variable defined in another if statement?
var in JavaScript is scoped to the containing execution context (e.g., the whole function's scope, or the whole global scope if the var is at global scope), not the block. JavaScript doesn't (yet) have block scope (ECMAScript6 looks likely to add it, via the new let keyword).
The code you've quoted is exactly equivalent to this:
var xx;
if(condition){
xx='sss';
}
//do something
if(condition){
console.info(xx);
}
This is covered by Section 10.5 of the specification, which describes what the engine does when entering a new execution context. (It's basically a two-phase process, first setting up all the declarations, and then executing step-by-step code.)
More: Poor misunderstood var
In JavaScript the scope is exacted to the closure (the last enclosing function block, or defaults to the window object). When a variable is declared anywhere within that function block it is hoisted to the top of the scope, so in essence a variable exists as undefined starting at the very top of the scope if it is declared anywhere in the scope.
Think of it like this, when the code begins executing it scans all the instructions for declarations and allocates the symbol name starting immediately.
console.log(x); // undefined
console.log(y); // error: Uncaught ReferenceError: y is not defined
var x;
for that matter you can take it to extremes:
console.log(x); // undefined, not an error
while (false) {
if (false) {
var x;
}
}
even though var x can't possibly be reached, and during execution would be optimized away completely. the engine will still hoist the variable to the top of the scope
hope this helps -ck
useful link: http://www.youtube.com/watch?v=taaEzHI9xyY&feature=youtu.be#t=42m57s
var declarations affect the entire scope of the smallest containing function or program. JavaScript is not block scoped.
Crock says:
Variable Declarations
All variables should be declared before used. JavaScript does not require this, but doing so makes the program easier to read and makes it easier to detect undeclared variables that may become implied globals. Implied global variables should never be used.
The var statements should be the first statements in the function body.
It is preferred that each variable be given its own line and comment. They should be listed in alphabetical order.
var currentEntry; // currently selected table entry
var level; // indentation level
var size; // size of table
JavaScript does not have block scope, so defining variables in blocks can confuse programmers who are experienced with other C family languages. Define all variables at the top of the function.
Use of global variables should be minimized. Implied global variables should never be used.
Note, this is changing with the let statement, and in current JavaScript (EcmaScript 5), the variable name in a catch block is block scoped.
javascript doesn't have block scope, so var xx='sss' is either locally scoped (if your sample code is inside a function) or globally scoped (if your sample code is not contained in a function).
JavaScript is a dynamic language, that isn't always picky about things like variable scoping. So, this "feature" allows you to write the code
if (condition) {
var xx = 'sss';
} else {
var xx = 'ttt';
}
// do something
if (condition) {
console.info(xx);
}
I would recommend avoiding this, since it makes your program harder to understanda and reason about.
If you declare a variable using var within a function, the variable is scoped to within that function. An if statement is not a function.
I'm assuming in this case both if statements are within the same function and therefore xx is in scope?
If a variable is declared inside a conditional statement, it is still available anywhere following the declaration in the containing function (or globally if the conditional is not in a function). However, it will equal undefined if the condition evaluates to false, unless the variable is later assigned a value.
If a local variable is referenced globally or in another function, a JavaScript error will occur. Depending on your browser, the error may say the variable "is not defined" or "is undefined". This is different from the variable equaling undefined like mentioned above, because a variable that equals undefined can still be referenced.