I don't understand why a var variable can be reassigned within a function, but the change also applies outside of the function. Why/How?
var c = 1;
function Fn() {
c = 2;
}
Fn();
c; // 2
Why isn't the value 2 limited to the scope of the function?
When I write c = 2 within a function, does the javascript engine automatically hoist a new var c outside of the function and assigns it the value undefined, which is then changed to 2 once Fn() is called?
It applies outside the function because, inside the function, you are changing the variable.
You are not creating a new variable that exists only inside the function.
Why isn't the value 2 limited to the scope of the function?
You didn't use var, let, const or any other method to create a variable in the scope of the function.
You are accessing the variable you already created in the wider scope.
When I write c = 2 within a function, does the javascript engine automatically hoist a new var c outside of the function and assigns it the value undefined, which is then changed to 2 once Fn() is called?
No. There isn't a new variable. There is only the c you already created outside the function.
This is a common complaint about javascript. Since you used "Var" it has a global scope, so even though you're within a new function when you use c=2 since it's already defined globally it's changed globally. Using "Let" helps define things local to the function and "const" defines globals as constants so they cannot be changed. This issue is particularly fun when you have two global variables with the same name in different JavaScript files and then reference both files to be used on a page. Globals should be used with caution.
When you start run this program, engine will store your variable which declared with "var" keyword in global object(window) then move on to get in the function, Engine will create Special Scope for function is called "Function Execution Context" (FEC) every declaration within the function will be available in this scope(FEC), so when Engine execute body of your function will find re-assignment for variable is called "c", it will looking for it in current scope, if didn't find it, will move on parent scope, in this case, Global Scope is its destination, will find the searched variable and then re-assign it with new value.
Read this wonderful article -> execution-context-how-javascript-works-behind-the-scenes
Related
I learnt about the term variable shadowing in Eloquent Javascript (Chapter 3), but I am trying to understand a precise, basic example of the concept.
Is this an example of shadowing?
var currencySymbol = "$";
function showMoney(amount) {
var currencySymbol = "€";
console.log(currencySymbol + amount);
}
showMoney("100");
That is also what is known as variable scope.
A variable only exists within its containing function/method/class, and those will override any variables which belong to a wider scope.
That's why in your example, a euro sign will be shown, and not a dollar. (Because the currencySymbol containing the dollar is at a wider (global) scope than the currencySymbol containing the euro sign).
As for your specific question: Yes, that is a good example of variable shadowing.
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. This outer variable is said to be shadowed...
so I believe your example is good.
you have a globally named variable that shares the same name as inner method. the inner variable will be used only in that function. Other functions without that variable declaration will use the global one.
Yes, your example is an example of shadowing.
The shadowing will persist in other scenarios too due to how closures work in JavaScript. Here's an example:
var x = -1;
function xCounter() {
var x = 0;
return function() {
++x;
return x;
};
}
console.log(x); // -1
counter = xCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(x); // still -1, global was never touched
Note that in this case, even when xCounter returns, the function it returns still has a reference to its own x and invocations of that inner function have no effect on the global, even though the original has long since gone out of scope.
We cannot define a variable more than once. But we can define in different scopes.
let name="tara"
if(true){
let name="ali"
if(true){
console.log(name)
}
}
variable shadowing is when a variable in a local scope uses its value instead of a variable in a parent scope.So the local variables value is shadowing over the parents.
in the above code there are two name variables defined but they are not defined in the same scope. so console.log(name) will check the local scope if it finds the name variable it uses it, if not it checks parent scope once finds it, it uses that one so it does not go the root.
var role = "Engineer";
console.log(role);
function displayRole(){
role = "developer";
console.log(role);
}
displayRole();
console.log(role);
Notice how the last line of code (console.log) prints developer yet it’s not inside the function scope. This is a good example of shadowing where by the role variable in the global scope has been overwritten by the role in the function scope.
To avoid shadowing, the variable in the function scope should be declared using the var keyword so that it becomes accessible to the function only.
Yes, this is a good example of shadowing. A global scope variable is said to be shadowed by a block scope variable when both have the same name. This is happening in your code and the block scope is shadowing the global scope.
I am doing a small work in JavaScript and I want to avoid problems, so I am asking beforehand.
Can I use two different variables and name them the same in different functions, given that one of these functions calls the other?
So, when I define the variable in the second function, will it interpret as two different variables, or will it rewrite the value of the original variable from the first function? (Or, will it throw an error due to the fact that a variable with that name already exists?)
Here is an example:
function first()
{
var a = somevalue;
second();
}
function second()
{
var a = differentvalue;
}
Thanks!
Variables declared inside a function are local to that function, and doesn't conflict with variables with the same name anywhere else.
You can even have a global variable with the same name, and the code inside the function will only see the local variable.
Example:
var a; // global variable
function first() {
var a; // local variable in first
second();
}
function second() {
var a; // local variable in second
}
(Global variables should of course be used as little as possible, but it's good to know that you can have a local variable that is unaffected by any global variables that may exist.)
A local variable inside a function is not only local to the function, it's actually local to that execution of the function. If you call the function again, a new variable is created, and if the function calls itself (recursion), each level will have it's own variable.
Yes you can, as long as you don't forget the var keyword : the scope of a variable is either the function in which it is declared or the global scope. There is no way from outside the functions to gain access to the variables they declare.
I'm studying variable scope in Javascript, and have come across the difference between variable declaration, and variable initialization. From talking to a developer I know, my understanding is that writing var before a variable declaration assigns the variable to the local scope, while not writing var before declaring the variable assigns the variable to the global scope. Is this true?
If writing var before declaring a variable does assign the variable to the local scope, is it necessary to write var later, when initializing the variable to keep it in the local scope? For example:
var someVariable;
// Do some things with JavaScript
someVariable = 'Some Value'
Since I declared someVariable in the local scope with var, but then initialized someVariable without using var, does JavaScript think that I just initialized one variable in the local scope, or that I declared one variable in the local scope, and then declared and initialized another variable in the global scope?
Later on, when I want to change the value of someVariable again, do I need to write var before the variable expression, or will JavaScript know that I'm changing the value of an already declared local variable? Technically speaking, how does JavaScript know when I'm changing the value of an already declared local variable, and when I'm declaring and initializing a global variable?
var something = "Initial value."
This means: "create a variable in the local scope and give it an initial value". The local scope means the function in which you use this statement.
something = "New value."
This means: "find variable 'something' in the nearest scope, and assign it a new value".
If you use the second statement without ever using the first, the statement will look for any definition of something in progressively bigger scopes (the function that contains your function, if it exists, the function that contains that, etc., until it reaches the global scope). If it finds something, it will assign to an already existing variable. If it finds nothing, it will create a global variable with that name.
If you use var first, you simply ensure that this search always stops at local scope.
These are the same:
var x;
// ...
x = 1;
...and...
var x = 1;
Both define a variable in the local scope and assign a value to it. If you want to change the value of the variable later in the same scope you can simply reference it by name:
x = 2;
If you're in a different scope however, unless the variable was declared in the global scope in the first place you will not be able to access it (it's "out of scope"). Attempting to do so will define a variable with that name in the global scope.
function a(){
var x = 1;
}
function b(){
x = 2; // 'x' in a is out of scope, doing this declares a new 'x' in global scope
}
a();
b();
When referencing a variable in the same scope it was declared, you do not need to prefix it with var, though you can:
var x = 1;
// ...
var x = 2;
...there's no need to do that. While it assigns 2 to 'x', it logically has no effect since var is already in local scope. If x had been declared globally however:
var x = 1;
function a(){
var x = 2;
console.log(x);
}
a();
console.log(x);
This will print first '2' and then '1'. By referencing x preceded with var in the function, it applies the local scope to the variable. Once the function completes the variable's original scope is restored (or the re-scope is lost, if you want to look at it that way). Thanks to #zzzzBov for pointing this out.
Hope this helps.
my understanding is that writing var before a variable declaration assigns the variable to the local scope, while not writing var before declaring the variable assigns the variable to the global scope. Is this true?
Not entirely.
function foo() {
var a = 1;
function bar() {
a = 2; // Still in the scope of foo, not a global
}
}
Since I declared someVariable in the local scope with var, but then initialized someVariable without using var, does JavaScript think that I just initialized one variable in the local scope, or that I declared one variable in the local scope, and then declared and initialized another variable in the global scope?
There is only one someVariable in that example.
Later on, when I want to change the value of someVariable again, do I need to write var before the variable expression
var scopes a variable for the entire function, no matter where in the function it appears.
If you define a variable using var, you can refer to the same variable without using the var keyword over and over. These refer to the same variable:
var someVariable;
//...code...
someVariable = 'rawr';
If you did use the var keyword every time you were changing the variable, you wouldn't get separate variables. The newest declaration would just overwrite the oldest declaration. So there's no point in using the var keyword except for initialization. To change the value of someVariable, you can just make assignments to the variable name like in the above example.
Basically, using var will create a new variable if there is no variable in that scope with the same name.
Now take this code for example:
var someVariable = 'initialized';
function test1(){
//this someVariable will be a new variable since we have the var keyword and its in a different scope
var someVariable = 'test1';
console.log(someVariable);
}
function test2(){
//because there is no var keyword this refers to the someVariable in the parent scope
someVariable = 'test2';
console.log(someVariable);
}
console.log(someVariable); //initialized
test1(); //test1
console.log(someVariable); //initialized
test2(); //test2
console.log(someVariable); //test2
With this example you can see that depending on what you want the code to do, you could be having problems. If you wanted test2 to act like test1 and forgot to use the var keyword you would be confused when you were expecting someVariable to be initialized and instead it was test2.
But you could have also purposely not used the var keyword because you wanted test2 to update the parent variable. So it is important that you use the var keyword correctly.
Not using var when initializing variables will create the variable on the global scope. This is not good practice. If you want variables on the global scope, manually put them there. i.e. window.someVariable = 'initialize'; That way anyone else that sees your code knows that you made it a global variable on purpose.
function onMouseClickFunction() {
$mapCanvas.click(function (e) {
var x = cursor.getCursorPositionInCanvasX(e.pageX),
y = cursor.getCursorPositionInCanvasY(e.pageY);
what is the variable scope in this example is it function onMouseclickFunction or perhaps the anonymous function of jquery?
What i ment is that javascript uses hoisting creating variables at the top of its parent function, so where is hoisting done in this example?
Every variable properly declared will always have a local scope to the current function.
Since you're using the var statement properly, your x and y variables are local to your anonymous function.
If you want to be able to access those variables from your onMouseClickFunction function, you should declare them outside your click event handler. You'll still have access to them from within the click handler, since that function itself is declared within the onMouseClickFunction function.
This is known as JavaScript's scope chain lookup: if a variable you're using has not been declared within the local scope, JavaScript will look for it in the scope just above the current one (which in the case of your anonymous function is the outer onMouseClickFunction). If it's not declared there either, it'll keep on looking all the way up the scope, till it reaches the global scope.
If the variable is not found anywhere through the scope chain, it'll be declared as a new variables in the global scope. That's why it's imperative to always declare your variables with a var statement, as you've done.
Assuming you mean the variables x and y, then it is the anonymous function passed to click().
var always scopes to the current function.
What i ment is that javascript uses hoisting creating variables at the top of its parent function, so where is hoisting done in this example?
Hoisting means that when you use var, the variable will be scoped for the function, even if you have previously tried to use it.
i.e.
function () {
var x = 1;
function () {
alert(x);
var x = 2;
}
}
If the inner function was called, it would alert undefined because var x = 2 creates a new x in the scope of the inner function (var is hoisted), but the assignment doesn't take place until after the alert (since the assignment is not hoisted).
All the var statements in the question appear at the top of the function they appear in, so hoisting makes no difference.
It would be the latter (the anonymous function), since that's the function in which the variables are being declared.
What you have created here is a closure.
As such, the anonymous function would inherit the scope of onMouseClickFunction, but the variables x and y are only in the scope of the anonymous function.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between using var and not using var in JavaScript
var foo = 1;
foo = 1;
What is the difference between above two lines ?
Basically, var declares a variable and you can also assign to it at the same time.
Without var, it's assigning to the variable. Assigning will either assign to an existing variable or create a global variable of that name then assign to it.
Outside of functions, that means there's no real difference (in principal) if the variable does not already exist. Both create the global variable foo in that case.
Within a function, there's a huge difference. The first creates a variable local to the function regardless of whether or not it exists elsewhere.
The second will create a global variable if it doesn't exist, or simply change the value if it does exist.
In order to keep code as modular as possible, you should always use var unless you are specifically wanting to change existing global variables. That means declaring all globals outside of functions with var and declaring all locals with var.
foo = 1 will put foo in the last scope where foo was defined, or the global scope. var foo = 1 will put the variable in the current scope (i.e. the current function).
In first case foo will be available in the same scope where it is defined, i.e. it will be local variable.
In second case foo is a global variable, located in global scope.