This is a thought exercise. I'm not doing anything with this code and the purpose is to better understand how closures work.
Thought Process:
x === 10 in global scope.
outer() function is called.
x === 20 in the global scope and local scope.
inner() function is called.
right side of 'var x' is expressed.
In x + 20, because x is not defined in local scope, it searches outer scope and finds x === 20.
var x = 20 + 20.
var x === 40.
return x.
result === 40.
However, the answer is 20. Why is this?
var x = 10;
function outer () {
x = 20;
function inner () {
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;
When the inner() function is called, the first thing that happens is var x.
This means the JavaScript interpreter first creates a variable named x to which it assigns undefined.
Then it runs the assignment expression x + 20, which is equivalent to undefined + 20 which is NaN.
Your variable result has nothing to do with your inner() function as you have a local variable (because of that var x) and you ignore the returned result.
In other words, your code is equivalent to just this:
var x = 10;
function outer () {
x = 20;
}
outer();
var result = x;
Because your inner function defined a local var x which will hide the global variable outside. And the outer function uses the global variable x and assign it to 20. Obviously, the global x is 20. Javascript will define every local variable before you call the function in the prototype chain.
var x = 10;
function outer () {
x = 20;
function inner () {
alert(x); // alert undefined
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;
Related
If I declared a variable at the top of a Javascript file like:
let x = 3;
How can I change it in a function later? I know you can use window.x with variables set by var, but how do you change it if it was declared by let?
let x = 3;
function myFunction(){
x = 4;
};
You have set a global variable x. It is available globally. Your function changes that global variable to 4. Simple as that.
let x = 3;
function myFunction(){
x = 4;
};
console.log(x) // 4
To perhaps expand on this, what if you were to re-declare x inside myFunction()? That would shadow the global x you declared at the top. Global x would still be 3 even after you ran the code, but x would be 4 inside the function.
let x = 3;
function myFunction(){
let x = 4; // this will now shadow the global x at the top
console.log(x);
};
console.log(x) // 3
And if you were to run myFunction()...
myFunction(); // 4
This question already has answers here:
What does var mean in Javascript? [closed]
(2 answers)
Closed 3 years ago.
I can't understand why the x after test won't become 30 but still remains 10
<script>
function test(){
var x = 30;
y = 40;
}
</script>
<script>
var x = 10;
var y = 20;
document.write("before test, x: " + x + ", y: " + y + "<br/><br/>");
test();
document.write("after test, x: " + x + ", y: " + y + "<br/><br/>");
</script>
This is because by declaring var x = 30;, you create a variable named x that exists only in the function's scope.
The variable y, however, is only defined at top-level. So when you run the function test, you edit the local x variable, and the global (top-level) y variable.
When you define variables they are hoisted at top of its scope. Let me show you how your current code:
function test(){
var x = 30;
y = 40;
}
var x = 10;
var y = 20;
test();
Will run like this:
// global scope
var x; // x is undefined
var y; // y is undefined
function test() {
// function scope
var x; // x is undefined inside this scope
x = 30; // x is assigned with value 30
y = 40; // y is assigned with value 40
// the global scope y value is assigned
}
x = 10; // x is assigned with value 10
// the global scope x value is assigned
y = 20; // y is assigned with value 20
// the global scope y value is assigned
test();
// when calling test,
// you see x is assigned with its function scope
// and y is assigned with its global scope
// so, at this point
// x becomes 10
// y becomes 40
You can read more about var here in the docs. Also, look in the scope, global scope and local scope.
Also, note that let and const works differently. They are scoped in the block. You can read them in the corresponding links which are linked here in.
Why does z() execution context not override global x variable?
var x = 10;
function z(){
var x = x = 20;
}
z();
console.log(x); // why is 10 printed? Shouldn’t it be 20.
var a = b = c = 0;
It means b and c are being declared as globals, not locals as intended.
For example -
var y = 10;
function z(){
var x = y = 20; // global y is overridden
}
z();
console.log(y); // value is 20
Going by above logic, x = x = 20 in z() means x is global which overrides the local x variable but still global value of x is 10
The internal x declaration is hoisted to the top of the function, and overshadows the x of the external scope. Your code actually does this:
var x = 10;
function z(){
var x;
x = x = 20;
}
z();
console.log(x); // why is 10 printed? Shouldn’t it be 20.
Why does z() execution context not override global x variable?
var x = 10;
function z(){
var x = x = 20;
}
z();
console.log(x); // Why is 10 printed? Shouldn’t it be 20.
var a = b = c = 0;
It means b and c are being declared as globals, not locals as intended.
For example:
var y = 10;
function z(){
var x = y = 20; // Global y is overridden.
}
z();
console.log(y); // Value is 20.
Going by above logic, x = x = 20 in z() means x is global which overrides the local x variable but still global value of x is 10.
function z(){
var x = x = 20;
}
Due to hoisting, this effectively gets turned into:
function z(){
var x;
x = x = 20;
}
So every instance of x in that function is referring to the local variable, not the global variable.
var x = x = 20;
is interpreted as
var x;
x = (x = 20);
so global x is not pointed.
var x = 10;
function z(){
var x = x = 20;
}
z();
console.log(x)
The local first x. The second x will not be hoisted because we already have x hoisted. So the x will be 20 locally but 10 as global.
For
var y = 10;
function z(){
var x = y = 20; // global y is overridden
}
z();
console.log(y); // value is 20
The x will be hoisted locally but the y will not hoist locally because it is not declared so it will leak to the global scope which is assigned 10. The global scope got changed locally to become 20. So that is why you are getting 10.
This question already has answers here:
Javascript scoping of variables
(3 answers)
Closed 6 years ago.
i have this code in java script
var x = 5;
function f(y) { return (x + y) - 2 };
function g(h) { var x = 7; return h(x) };
{ var x = 10; z = g(f) };
z value is 15. why?
the expression (x+y)-2 is being evaluated as (10+7)-2.
why does x get the value of 10, and not the value of the previous
block, where x = 7?
thanks for the help
You can completely delete the first assignment. It gets overwritten before you call g(f).
Also, you can remove the parentheses of the last block as there is no block scope in JS (actually block scope got introduced with let, so you wanna use that instead).
var x = 5;
function f(y) {
// global variable x is 10 -> 10 + 7 - 2 = 15
return (x + y) - 2;
}
function g(h) {
// x gets declared locally - local value will be used
var x = 7;
return h(x); // f gets called with y = 7
}
x = 10; //global x gets changed
z = g(f);
... and always place your semicolons. Even though they maybe look optional but in some cases they are obligatory.
Value of variable x is 10 at global execution context.
When function f is finally called the value of the argument which is y, this y actually represent value of x at local execution context of function g, here x is 7.
var x = 5;
function f(y) {
return (x + y) - 2 ;
}; // value of global var x is 10, value of parameter passed is 7
// this value comes from the local var x of g function's execution context.
function g(h) {
var x = 7; return h(x); };
{ var x = 10; z = g(f); };
console.log(z);