Scope of variable in if - javascript

function a(){
var x,y,a,b;
var a=2;
var b=2;
if (true) {
var a,b;
b=1;
a = 1;
}
alert(a)
}
a();
Why the result is not 2? I wonder why redeclaration of a and b in if condition does not create a new variable a and b? Is there any rule I can follow?

In javascript, variables declared with var are hoisted to the top of the function. This means that the scope rules you are expecting do not work. This is addressed in the ES6 standard with the let keyword which will scope how you were expecting. See the following site for more info on let. You should note that the ES6 standard is new and is not widely supported. You can use the standard now by using a transpiler such as Babel. You can play with this on playgrounds such as codepen.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let

"var" will create local variable in current scope, but as the scope in javascript is function level, and in the snippet mentioned we are in the same function, javascript interpreter thinks that variable declaration inside if block is re-declaration of the same variable in the same function scope.

Related

Scope within for loop

I've been starting to use IIFEs within for-loops, like so:
var currentItem = 2; // IIFE helps prevent variable collision
for(var i = 0; myArray.length < i; i++){
(function(){
var currentItem = myArray[i];
// do stuff
})();
}
The main reason I've been doing this is to give some scope to the for-loop, so the variables don't escape this scope. Are there any negative effects/performance hits of doing so? And if so, what is the extent of their harm? Thanks!
Yes there is a performance cost in wrapping the body of a for statement into an anonymous function. The problem is the cost of creating a new function object for each iteration. That is, for each iteration a new function object is created with its own scope.
Performance comparison named vs anonymous function
This is a small comparison between named function and function declaration which may help you to understand the impact over the performance of your code. Note, in your case, the problem is not the anonymous function, but rather the cost of creating the function object.
ES6
I understand, you are trying to scope your variable to the for. I would suggest another solution to achieve this. If you can, try to use let keyword from ES6.
The let keyword has been introduced to overcome all of var's defects, such as this one. let allows you to declares variable that are limited in scope to the for block.
From the documentation:
let allows you to declare variables that are limited in scope to the
block, statement, or expression on which it is used. This is unlike
the var keyword, which defines a variable globally, or locally to an
entire function regardless of block scope.

Is declaring a function variable required (in Javascript)?

The teachers at my school are teaching us we have to specifically declare function variables like so:
function something(var1, var2)
{
var var1, var2;
console.log(var1);
console.log(var2);
}
something("Totally", "Cool");
However I can't seem to find any topics about this, so my question is, is this even required? Isn't it perfectly normal and OK to just leave the var var1, var2; out?
If so, is this stated somewhere in the W3C JavaScript documentation?
I mean it works either way, but if it works without... Cleaner code I'd say :P
Code I'm talking about: http://pastebin.com/y5B2aznc
Thanks!
in javascript, the scope of variables depends on how they are declared:
if you declare the variable when you define it, the scope of the variable is global
if you declare it using the var keyword, the scope of the variable is within the function
if you use the newer ES6 let keyword, the scope of the variable is within current block
so it is better to not use global variables and always limit the scope of your variables.
Here are a few references explaining the variable scopes in javascript:
What is the scope of variables in JavaScript?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/
you should also definitely read Douglas Crockford's Javascript, the good parts:
http://shop.oreilly.com/product/9780596517748.do
http://javascript.crockford.com/‎
edit:
in your particular case, it is not useful:
function something(var1, var2)
{
var var1, var2;
console.log(var1);
console.log(var2);
}
as you give those variables as parameters of the function, they are already declared within the function scope, so declaring them again as var is redundant, and you can safely remove that line.
function something(var1, var2)
{
console.log(var1);
console.log(var2);
}
In your particular case, all the variables passed as arguments are local variables just like the variables you declare with var. So re-declaring them with var is redundant.
But a better practice is to leave the arguments with their original values, and do stuff with them storing the results in other local variables. E.g.:
function something(var1, var2)
{
var varAlt1 = var1.toUpperCase(), varAlt2 = var2.toLowerCase();
console.log(varAlt1);
console.log(varAlt2);
}
Omitting the keyword var in the declaration will result in the variables being global and not having their scope limited to the function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
If you don't use the var statement then the variables will be created in the global scope which is the window object. This is a bad practice since you're polluting the global scope and can affect other scripts/functions.
I suggest you read on the var statement on MDN. Also, here's a nice article on Javascript scope.
Edit: I didn't notice that the variables you're declaring are also the function parameters. In this case, the var statement will have no effect since re-declaring an already declared variable is a no-op (does nothing).
If you want to know more about the var statement and how scope is handled in Javascript, may I suggest reading this article?

Defining JavaScript variables inside if-statements

Is defining JavaScript variables inside if-statements correct?
if(a==1){
var b = 1;
} else {
var b = 0;
}
I know the code above will work, however, WebMatrix highlights the variables.
Should I define the variables outside the if-statement? Or the first option's correct? Or it doesn't really matter?
var b = '';
if(a==1){
b = 1;
} else {
b = 0;
}
As of the official release of ES2017 spec (2017-07-08), EcmaScript does support true block scope now using the let or const keywords.
Since ECMAscript doesn't have block scope but function scope, its a very good idea to declare any variable on the top of your function contexts.
Even though you can make variable and function declarations at any point within a function context, it's very confusing and brings some weird headaches if you aren't fully aware of the consequences.
Headache example:
var foo = 10;
function myfunc() {
if (foo > 0) {
var foo = 0;
alert('foo was greater than 0');
} else {
alert('wut?');
}
}
Guess what, we're getting a 'wut?' alert when calling myfunc here. That is because an ECMAscript interpreter will hoist any var statement and function declaration to the top of the context automatically. Basically, foo gets initialized to undefined before the first if statement.
Further reading: JavaScript Scoping and Hoisting
Note that ECMAscript 6 does support block-level variables using the 'let' rather than the 'var' keyword. While variables declared with 'var' are hoisted to be function-scope regardless of where they are declared, those defined using 'let' are scoped to the enclosing block only.
Putting a var inside an if statement is not against "the rules" of the language, but it means that, because of var hoisting, that var will be defined regardless of whether the if statement's condition is satisfied.
Because JavaScript's variables have function-level scope, your first example is effectively redeclaring your variable, which may explain why it is getting highlighted.
On old versions of Firefox, its strict JavaScript mode used to warn about this redeclaration, however one of its developers complained that it cramped his style so the warning was turned off. (Current versions of Firefox support a block-level variable declaration syntax.)
See function four on What is the scope of variables in JavaScript?
As of 2012, there's no block-level scope in JavaScript. So your first version is fine: the variables are defined in the scope outside the if block.

Is using 'var' to declare variables optional? [duplicate]

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 7 years ago.
Is "var" optional?
myObj = 1;
same as ?
var myObj = 1;
I found they both work from my test, I assume var is optional. Is that right?
They mean different things.
If you use var the variable is declared within the scope you are in (e.g. of the function). If you don't use var, the variable bubbles up through the layers of scope until it encounters a variable by the given name or the global object (window, if you are doing it in the browser), where it then attaches. It is then very similar to a global variable. However, it can still be deleted with delete (most likely by someone else's code who also failed to use var). If you use var in the global scope, the variable is truly global and cannot be deleted.
This is, in my opinion, one of the most dangerous issues with javascript, and should be deprecated, or at least raise warnings over warnings. The reason is, it's easy to forget var and have by accident a common variable name bound to the global object. This produces weird and difficult to debug behavior.
This is one of the tricky parts of Javascript, but also one of its core features. A variable declared with var "begins its life" right where you declare it. If you leave out the var, it's like you're talking about a variable that you have used before.
var foo = 'first time use';
foo = 'second time use';
With regards to scope, it is not true that variables automatically become global. Rather, Javascript will traverse up the scope chain to see if you have used the variable before. If it finds an instance of a variable of the same name used before, it'll use that and whatever scope it was declared in. If it doesn't encounter the variable anywhere it'll eventually hit the global object (window in a browser) and will attach the variable to it.
var foo = "I'm global";
var bar = "So am I";
function () {
var foo = "I'm local, the previous 'foo' didn't notice a thing";
var baz = "I'm local, too";
function () {
var foo = "I'm even more local, all three 'foos' have different values";
baz = "I just changed 'baz' one scope higher, but it's still not global";
bar = "I just changed the global 'bar' variable";
xyz = "I just created a new global variable";
}
}
This behavior is really powerful when used with nested functions and callbacks. Learning about what functions are and how scope works is the most important thing in Javascript.
Nope, they are not equivalent.
With myObj = 1; you are using a global variable.
The latter declaration create a variable local to the scope you are using.
Try the following code to understand the differences:
external = 5;
function firsttry() {
var external = 6;
alert("first Try: " + external);
}
function secondtry() {
external = 7;
alert("second Try: " + external);
}
alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7
The second function alters the value of the global variable "external", but the first function doesn't.
There's a bit more to it than just local vs global. Global variables created with var are different than those created without. Consider this:
var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object
Based on the answers so far, these global variables, foo, bar, and baz are all equivalent. This is not the case. Global variables made with var are (correctly) assigned the internal [[DontDelete]] property, such that they cannot be deleted.
delete foo; // false
delete bar; // true
delete baz; // true
foo; // 1
bar; // ReferenceError
baz; // ReferenceError
This is why you should always use var, even for global variables.
There's so much confusion around this subject, and none of the existing answers cover everything clearly and directly. Here are some examples with comments inline.
//this is a declaration
var foo;
//this is an assignment
bar = 3;
//this is a declaration and an assignment
var dual = 5;
A declaration sets a DontDelete flag. An assignment does not.
A declaration ties that variable to the current scope.
A variable assigned but not declared will look for a scope to attach itself to. That means it will traverse up the food-chain of scope until a variable with the same name is found. If none is found, it will be attached to the top-level scope (which is commonly referred to as global).
function example(){
//is a member of the scope defined by the function example
var foo;
//this function is also part of the scope of the function example
var bar = function(){
foo = 12; // traverses scope and assigns example.foo to 12
}
}
function something_different(){
foo = 15; // traverses scope and assigns global.foo to 15
}
For a very clear description of what is happening, this analysis of the delete function covers variable instantiation and assignment extensively.
var is optional. var puts a variable in local scope. If a variable is defined without var, it is in global scope and not deletable.
edit
I thought that the non-deletable part was true at some point in time with a certain environment. I must have dreamed it.
Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/
function doMe(){
a = "123"; // will be global
var b = "321"; // local to doMe
alert("a:"+a+" -- b:"+b);
b = "something else"; // still local (not global)
alert("a:"+a+" -- b:"+b);
};
doMe()
alert("a:"+a+" -- b:"+b); // `b` will not be defined, check console.log
They are not the same.
Undeclared variable (without var) are treated as properties of the global object. (Usually the window object, unless you're in a with block)
Variables declared with var are normal local variables, and are not visible outside the function they're declared in. (Note that Javascript does not have block scope)
Update: ECMAScript 2015
let was introduced in ECMAScript 2015 to have block scope.
The var keyword in Javascript is there for a purpose.
If you declare a variable without the var keyword, like this:
myVar = 100;
It becomes a global variable that can be accessed from any part of your script. If you did not do it intentionally or are not aware of it, it can cause you pain if you re-use the variable name at another place in your javascript.
If you declare the variable with the var keyword, like this:
var myVar = 100;
It is local to the scope ({] - braces, function, file, depending on where you placed it).
This a safer way to treat variables. So unless you are doing it on purpose try to declare variable with the var keyword and not without.
Consider this question asked at StackOverflow today:
Simple Javascript question
A good test and a practical example is what happens in the above scenario...
The developer used the name of the JavaScript function in one of his variables.
What's the problem with the code?
The code only works the first time the user clicks the button.
What's the solution?
Add the var keyword before the variable name.
Var doesn't let you, the programmer, declare a variable because Javascript doesn't have variables. Javascript has objects. Var declares a name to an undefined object, explicitly. Assignment assigns a name as a handle to an object that has been given a value.
Using var tells the Javacript interpreter two things:
not to use delegation reverse traversal look up value for the name, instead use this one
not to delete the name
Omission of var tells the Javacript interpreter to use the first-found previous instance of an object with the same name.
Var as a keyword arose from a poor decision by the language designer much in the same way that Javascript as a name arose from a poor decision.
ps. Study the code examples above.
Everything about scope aside, they can be used differently.
console.out(var myObj=1);
//SyntaxError: Unexpected token var
console.out(myObj=1);
//1
Something something statement vs expression
No, it is not "required", but it might as well be as it can cause major issues down the line if you don't. Not defining a variable with var put that variable inside the scope of the part of the code it's in. If you don't then it isn't contained in that scope and can overwrite previously defined variables with the same name that are outside the scope of the function you are in.
I just found the answer from a forum referred by one of my colleague. If you declare a variable outside a function, it's always global. No matter if you use var keyword or not. But, if you declare the variable inside a function, it has a big difference. Inside a function, if you declare the variable using var keyword, it will be local, but if you declare the variable without var keyword, it will be global. It can overwrite your previously declared variables. - See more at: http://forum.webdeveloperszone.com/question/what-is-the-difference-between-using-var-keyword-or-not-using-var-during-variable-declaration/#sthash.xNnLrwc3.dpuf

About scoping in JavaScript

I need to have some information about the scoping in JavaScript. I know that it supports lexical (static) scoping, but, does not it support dynamic scoping as well?
I think you're confused because Javascript uses static scoping but at function-level, not at block level like usual structured languages.
var foo = "old";
if (true) {var foo = "new";}
alert (foo == "new")
So be careful, blocks don't make scope!
That's why you sometimes see loops with functions inside just to enable variables whose scope is inside an iteration:
functions = [];
for(var i=0; i<10; i++) {
(function(){
var local_i = i;
functions[local_i] = function() {return local_i;}
})();
}
functions[2]() // returns 2 and not 10
As far as I understood; Javascript has two kinds of variables which are global and local variables. But, suppose we have a variable called x, which is defined as global, and defined in the static parent of the scope of place where x is referenced. In this case, x takes the value of the global variable. Thus, global variable has higher priority than local ones. And, when there is no any global variables, x finds the declaration through the static chain which makes me think that Javascirpt is staticaly scoped language.
Am I right at above?

Categories

Resources