This question already has answers here:
Javascript function scoping and hoisting
(18 answers)
Closed 3 years ago.
var x = 2;
function fun() {
x = 3;
var x = 4;
document.write(x);
}
document.write(x);
fun()
document.write(x);
Can someone help me understand the flow of control. Why is the output 242 when it looks like output should be 243. All help will be greatly appreciated.
This due to hoisting. The variable x which is local inside fun is brought to top of scope and then assigned the value 3 and after that assign value 4. So line x=3; is not changing global variable but its changing local variable. The code acts like
function fun(){
var x;
x=3;
x=4;
document.write(x);
}
When you modify the x=3 it is not actually changing the global variable x but the variable declared in the function block (as var variables have function scope). As the declaration var x is hoisted to the top and then the modification to x = 3 happens
<script>
var x=2;
function fun(){
//var x; hoisted to the top;
console.log("x is hoisted here and uninitialized value will be", x)
x=3; //initialized, actually referring to the variable declared in the function scope
var x = 4; //declared but hoisted at the top
document.write(x);
}
document.write(x);
fun()
document.write(x);
</script>
To really change the variable at the global scope, use window.x to refer to it:
<script>
var x=2;
function fun(){
window.x=3; //modifying the global variable 'x`
var x = 4;
document.write(x);
}
document.write(x);
fun()
document.write(x);
</script>
Related
This question already has answers here:
typeof of a function not returning correct value but undefined
(2 answers)
Closed 4 years ago.
The example below must output for sure function, as the value of x is "1" (integer) and then we are passing a parameter named "f" (of a function). It doesn't matter whether this function does something or is blank, but I am sure -- that variable f --> points to function. so typeof(f) will surely return function.
Now, adding of an integer and "function" (as typeof always returns a string) is going to be a string --> 1function.
Now, amazingly the output is "1undefined". How?
<script>
var x = 1;
if (function f(){}) {
x += typeof f;
}
console.log(x);
</script>
As per answer by Ellepsis that declarations don't take inside if() braces and only boolean is returned. Explain this then, why is it returning 3?
<script>
var x = 1;
if (y = 2) {
x = x + y;
}
console.log(x);
</script>
if (function f(){}) {
A function declaration will create a variable with the same name in the current scope.
A function expression will only create a variable with the same name inside itself.
So the variable f only exists:
if (function f(){ })
^^^^
here
The function expression itself evaluates as a function, which the if statement picks up as a truthy value but there is no f variable in scope.
Explain this then, why is it returning 3?
You are explicitly assigning a value to a variable. That variable remains in scope.
You would get the same effect if you did this:
if (f = function f(){}) {
So:
(function f(){})
Creates a function
Names the function f
Creates a variable inside the function called f containing a reference to a function
Evaluates as a function, which is a true value, which is tested by the if
While:
(f = function f(){})
Creates a function
Names the function f
Creates a variable inside the function called f containing a reference to a function
Creates a variable f outside the function
function f(){} evaluates as a function and is assigned to f by the =
f = function f(){} also evaluates as a function, which is a true value, which is tested by the if
You are getting undefined because function f is not defined in the code anywhere. Writing the function inside an if statement does not define the function. The code just assumes it as a truthy value, a condition for the if statement but in real f does not exists. You can define f outside and it will work fine or you can just perform the assignment in the if and then also it will work
var x = 1;
if (f=function(){}) {
x += typeof f;
}
console.log(x);
var x = 1;
var f;
if ( f = function() {} ) {
x += typeof f;
}
console.log(x);
This question already has answers here:
Does JavaScript pass by reference? [duplicate]
(13 answers)
Closed 7 years ago.
Why doesn't this work and is there any way to get it to work?
Im pretty sure it doesn't work because of variable scoping in javascript, but I can't think of any ways to get it to work.
Code
var x = 5;
var z = function(y) { y = 10; };
z(x);
console.log(x) // Outputs 5 instead of 10
var x = 5
var z = function(y) { y = 10; }
console.log(x) // Outputs 5 instead of 10
Where exactly did you changed X? you dont have X and you did not call the function as well.
I assume you wish to do this:
var x = {x: 5}
var z = function(y) { y.x = 10; }
z(x);
console.log(x.x) // Outputs 10
The code is using x as variable on an object instead of a primitive number which is passed by value and not by reference and thus cannot be modified.
Using object you can modify the attributes (properties) of the object
X won't change for a couple reasons. The first is that you are modifying the parameter y inside of the function. If you passed an object this would work as those are passes by reference. It would also work if you changed x directly instead of passing it as an argument.
The second reason is that you never ran the function. You need to call z with z()
What happens when you invoke the function z is that the parameters get initialized and assigned the value you passed in.
So the function might read something like
var y = 5;
y = 10;
and so, the y that is in the scope outside of the function, remains unchanged because this y is actually a whole new y variable just for this function's scope.
var x = 5;
var z = function(y)
{
y = 10;
//assigned value 10 to the function parameter variable y.
//You haven't done x=y or x=10 and so how do you expect the value of x to change?
}
console.log(x) // Outputs 5 instead of 10
Change it to:
var x = 5 ;
var z = function(y)
{
x = 10; //changed value of x to 10
}
console.log(x) // Outputs 10
The problem is not related to vatiable scope at all.Your variable x is global since it is outside the function.
AND YES,you can change it's value inside a function.But the problem with your code was that you never changed the value of x.
If this is what you intended to do:
z(x); //x=5 is passed to the function z
function(y)
{
y=10; //initially the value of y is 5.Since you have passed x.
//Doing y=10 does not change the value of x because y is another variable.The value of x was copied to y and y is not x.
x=y;//You have assigned 10 to x
}
console.log(x); //outputs 10
Changing the value of the function parameter does not change the value of the variable whose value you passed to the function.You are actually passing the value of x to y that is you are passing 5 to y and not the variable itself.
You are not passing the variable reference.You are just passing the value.
I was reading about hoisting in mozilla, and noticed an example explaining how a variable can leak outside of the function scope:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#Initialization_of_several_variables
The example says,
var x = 0;
function f(){
var x = y = 1; // x is declared locally. y is not!
}
f();
console.log(x, y); // 0, 1
// x is the global one as expected
// y leaked outside of the function, though!
I don't understand what is happening here. I am looking for a technical explanation more than anything. How is y accessible outside at this point?
Edit: I understand how this function is behaving, and I should clarify and say I wanted an understanding of what is happening in the code and memory (ex, pointers, etc..).
you have var x = y = 1 which means that x is declared inside but y is not, var doesn't apply to y in this case, that's why it's leaked outside the function
This is breakdown of the statement:
var x = y = 1;
\___/ \____/
identifier initializer
\____________/
variable declaration
In this case the initializer is another assignment. Due to variable hoisting, this statement is evaluated as follows:
var x;
x = y = 1;
As you can see, y is not declared. Assigning to an undeclared variable creates a global variable (implicitly).
var x = 0;
function f(){
var y = 1;
var x = 1;
}
f();
console.log(x, y);
Try the above code. The problem is that you didn't include a var in front of y. The result is that y is hoisted into global scope.
In JavaScript, variables are declared as soon as you use them, like this:
function f(){
y = 1;
}
The problem is that y is not scoped within f(), like it would be in most other programming languages. So you can do something like this:
function f(){
y = 1;
}
console.log(y);
And you will see 1 on the console.
This is generally considered a bad practice, because it pollutes your namespace and can lead to subtle, hard to track down bugs.
To avoid this, always use let or var to explicitly declare variables, like this:
function f(){
let y = 1;
}
// the y declared in f() is not accessible out here
console.log(y)
This should give you an error like: "Uncaught ReferenceError: y is not defined" on your console.
For more details, read this page, specifically the section 'Automatically Global': http://www.w3schools.com/js/js_scope.asp
In the example you gave above the problem is more subtle, because x is scoped properly, but the short-hand declaration of y makes it globally scoped:
function f(){
let x = y = 1;
}
EDIT 2022: Updated to recommend let over var. Here is an explanation of the difference.
i have a global variable x, which has the same name as that of the inner function
when i execute the test function it also executes the function which has same as that of the global variable, this function contains assigns value to the variable which has the same name as that of the function, now when in the next line it alerts the value of the x, it alerts 2, but when after the execution of the test function if you alert the x it still alerts 10... y?
eg
var x =10; //assigns value 10 to global variable x
function test(){
function x () {
x = 2; //assigns value x
alert(x); // x =2
}
x(); //calls x
}
test(); //call function test
but if you alert x, then it gives 10...
why like this;
and if you do like this
var y =10; //assign value 10 to y
function test(){
function x () {
y = 2; //assign value 2 to y
alert(y); //alerts y is 2
}
x(); //call the function x
}
test(); //call the test function
and if you check y then also it is 2..
what is the difference between the two.. I know the behaviour of the second one..
but have no idea about the first one...
A function declaration does two things:
It declares a new variable in the current scope (with the same name as the function). This is the same as var x.
It creates a function and assigns it to that variable. This is the same as x = function x () { ... } except it is hoisted.
In the first example, the function declaration for x creates a variable x in the scope of test so when you x = 2;, you are overwriting the pointer to the function in x with 2 while leaving the other variable x (which exists in the wider scope and holds the variable 10 alone).
This can be demonstrated:
var x = 10;
function test() {
function x() {
x = 2; //assigns value x
}
alert("x inside test before calling x(): " + x)
x(); //calls x
alert("x inside test after calling x(): " + x)
}
alert("x outside test before calling test(): " + x)
test()
alert("x outside test after calling test(): " + x)
In the second example, the function is called y, so it doesn't create a new x in the narrower scope and x = 2 touches the original x.
The function keyword is similar to var -- they both make the name they define into a local variable. So there are two x variables: one whose scope is outside the test function, the other whose scope is inside the function. Assigning to the inner x has no effect on the outer x.
In your second version, you don't have a var or function declaration for y inside the function, so it accesses the global variable.
For more information, see
What is the scope of variables in JavaScript?
This question already has answers here:
How do I define global variables in CoffeeScript?
(9 answers)
Closed 10 years ago.
With javascript:
function myFunc() {
var x = 5;
};
console.log(x);
I get //undefined and with:
function myFunc() {
x = 5;
};
console.log(x);
I get 5
With coffeescript this variable var x = 5; is x = 5.
For example this is possible?:
myFunc ->
window.x = 5;
console.log window.x
Instead of:
myFunc ->
x = 5;
console.log x
My question is How I can differentiate a global variable of a local variable with CoffeeScript?
for global scope you should use functions like this:
myFunc = =>
#x = 5;
myFunc()
console.log x
example of generated code:
http://jsfiddle.net/Upward/wZ7w4/