Javascript Global vs Local Scope - javascript

I'm currently trying to understand Javascript's interesting take on global vs local scope.
My question is that why would the following returns undefined?
var a = 100;
function local() {
if (false) {
var a = 50;
}
alert(a);
}
Additionally, I ran this:
var a = 100;
function local() {
alert(a);
}
The result was a resounding: 100.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?

Because of hoisting.
It means every variable declaration get's popped to the top of the function so the actual code that runs is:
var a = 100;
function local(){
var a;
if (false)
a = 50;
alert(a);
}
It has very little to do with global VS. local, you simply hid the outer a variable with the inner a variable.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?
No
Regarding the question in the comment "In the case that I want to revert to using a global variable in case the if condition fails (which I intentionally did), how can I do so? ":
You can use eval:
var a = 100;
function local() {
if (false) {
eval('var a = 50;');
}
alert(a);
}
Live DEMO
But you should not!

JavaScript has function scope, not block scope (as many other programming languages). That means regardless where the var statement occurs (in your case, an if-branch that is not even executed), it declares a variable a in the function's local scope. It shadows the global a variable, but since it has no value assigned it returns undefined.
Is there some way that we can specify when we want the variable to be taken from the global scope, like a PHP global keyword, that we can use with Javascript?
You can access the variable as a property of the global object (window in browser environments):
var a = 100; // global
function loc() {
var a = 50;
alert(window.a); // 100
alert(a); // 50
}
loc();
However, you will hardly use this. Global variables are to be avoided in general, and in case of name clashes you should simply rename your local variable (for readability and maintainability at least).

I know that if a variable is in defined inside a function using var, then it will have Local Scope.
I also know that any function has easy access to Global variable.
When I tested following in Console of Browser, first output was undefined.
It means that function nwf() was unable to access Global variable nw1
This is due to reference error which highlights importance of Strict Mode
To avoid such scenario, never re-declare and/or initialize any variable with same name inside and outside any function, just unlike following:-
var nw1 = 1; // var creates global scope outside function
function nwf() {
alert(nw1);
var nw1 = 2; // var creates LOCAL scope inside function
alert(nw1);
};
nwf();

Related

Not understanding the concept of local and global variables

Ok so just a quick one... I REAAAAAALLLLY am not understanding scope at all. Do some reason whenever I put a variable inside of a function it's undefined. It seems the only way it works it to declare it OUTSIDE of a function. So what gives? Am I simply misunderstanding the concept of local and global variables? Because it seems global variables are the only ones that work...
Edit:
Simple example...
let a = 'something';
function myFunction() {
// Code block
};
This works 👆
But the following gives me undefined variables:
function myFunction() {
let a = 'something';
// Code block
};
First lets take a look at the differences between local and global variables.
LOCAL VARIABLES - Any variable defined inside of a function or loop. If the variable is defined in a certain function/loop, it can only be accessed in that function/loop.
For example:
function number() {
let a = 0;
// Can access a here.
}
// Cannot access a here.
GLOBAL VARIABLES - Any variable that is not defined inside of any function or loop. These variables can be accessed anywhere.
For example:
let b = 0;
function number() {
// b can be accessed here.
}
// b can be accessed here.
The scope of a variable is where it can be accessed in. For ex, a scope of a local variable that is defined inside of function number() is the number() function since it can only be accessed there.
One more quick thing (Credit to Mikael Lennholm) var doesn't scope a variable to a loop (or any non-function statement block), it only scopes it to the current function. To scope a variable to any statement block you have to use let/const
Now let's look at your examples:
Here is the first example:
let a = 'something';
myFunction();
function myFunction() {
console.log(a);
};
That works fine, and that's what you said.
Here is the second example you said doesn't work:
function myFunction() {
let a = 'something';
console.log(a);
};
myFunction();
But, if you click the run button, you'll actually see it does work, it does get logged. If you after this go and check in the console what the variable a is of course it will be undefined, since a can be only accessed in the myFunction() function, and the console is not in that function.
You said that the script doesn't work, it's most probably because of something else (if it was because of this there would be an error in the console). You can try posting the website here and I can help you.
Hope this helped you :)
Global variables are variables that you have access to them anywhere in your codes.
Local variables are limited to their scopes like a function, module, class and etc.
if you define a local variable it can be accessible in the nested level like closures.
if you define a global variable and you define the same name as local variable , the local overwrite the global, then be careful.

How should I access to overwritten variable in overwritten function?

I'm not able to understand of how should I get to particular variable a in next code:
var a = 1;
console.log(a);
function local() {
var a = 2;
console.log(a);
function local() {
var a = 3;
console.log(a);
function local() {
var a = 4;
console.log(a)
}
local();
}
local();
}
local();
I know this is artificial example but I can't go to sleep without the answer :)
So how should I get a particular variable a from any of overwritten function?
Thanks.
When you declare a variable in the local scope with the same name as a variable in a higher scope, the new declaration hides the higher scoped variable and there is NO way to access that higher scoped variable from the local scope.
This is just how Javascript is designed. There isn't some magic way around it. If you want access to the higher scoped variable, then don't declare a local variable with the same name. Pick a different name.
If the top-most variable is in the global scope, then you might be able to access that variable with a global prefix such as window.a or global.a (depending upon which environment you're running in). But, the intermediate variables that are not in the global scope are not accessible.
you can access global variables by the window object like this
var aa=11;
function my_func(){
var aa=22;
alert("local: "+aa+" global: "+window.aa);
}
but there is no way of accessing the local variables outside the function, as they do not really exist out there!

Is it possible to write a JS function with no access to global variables?

For better knowledge of what a function is using, etc.
Might also be faster for variable lookups if not accessing the global scope?
Suppose I have:
a = 5;
b = 5;
in the global scope. Is it possible to wrap the function below such that
function go() {
console.log(a);
}
would not have access to "a" and the global namespace and return
Uncaught ReferenceError: a is not defined
No, there is no way to completely prevent access to global variables. That said, you can provide it a different set of global variables: namely, run it in an iframe. This isn’t bulletproof, though, since it could then just use window.parent to access the global variables of the parent.
Yes. The example below is straight from MDN eval.
You could try this IF you could wrap your entire codebase in a single wrapper function so that all your objects and functions fall into local scope. (I am not sure how practicable this is but it works in Chrome and Firefox)
(function() {
var x = 2, y = 4;
function range(a,b){return [a,b];}
console.log("DIRECT", eval("x + y"), eval("range(3,4)")); // Direct call, uses local scope, result is 6
var geval = eval;
console.log("INDIRECT", geval("x + y"), geval("range(3,4)")); // Indirect call, uses global scope, throws ReferenceError because `x` is undefined
})()
I believe that no matter what the current scope is, there is always a way to get to the global object:
let ref_to_global = (function(){
return this;
}).call(null);
Then one can access any property of the global object directly:
let value = ref_to_global["a"];
This means there is no way to make global scope inaccessible, if that was a question.

Why can't I access variables inside a function?

If functions are objects in javascript, why can't I access the function scope defined variables?
I understand that in the code:
// variable test assigned an anonymous function
var test = function(){
var x = 5;
};
console.log(test.x); // undefined
// Even when the function is explicitly named:
function test(){
var x = 5;
}
console.log(test.x); // undefined
I don't need to get this working or anything; I just need to understand why functions are like this.
Thanks.
This would be one way to accomplish what you are trying:
function test() {
this.x = 5;
}
var foo = new test();
console.log(foo.x);
Using var x rather than this.x just declares a local variable
I believe it is because those variables only exist within the scope of the function you have defined. Outside the scope of that function they do not exist.
They are the equivalent of private members in a class of an object oriented language.
Alternatively you could have
function test() {
this.x = 5;
}
var testInstance = new test();
console.log(test.x);
Functions are objects, but that doesn't mean that any variable declared inside the function becomes a property of that function object. In fact, that would be terrible because you wouldn't be able to run a function more than once (since the second time, the variables would start with different values).
You can assign a property to a function object like this:
var test = function () {};
test.x = 5
The variable is visible only in the function and it is possible to access it only within the function, you can use global variable and then edot it insode the function.
You have created Local variables. Local variable can only be accessed within the function.
Try to understand about Local & Global JavaScript Variables
Local JavaScript Variables
Variables declared within a JavaScript function, become LOCAL to the function.
Local variables have local scope: They can only be accessed within the function.
function myFunction() {
var name = "roy";
// code here can use name
}
Global JavaScript Variables
A variable declared outside a function, becomes GLOBAL.
A global variable has global scope: All scripts and functions on a web page can access it.
var name = "roy";
// code here can use name
function myFunction() {
// code here can use name
}
var someName = function(){var x ...} /// only has local scope.
What is the scope of variables in JavaScript?
Will describe it better than I can. Good job on being curious and motivated.

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

Categories

Resources