Hoisting in javascript - javascript

I asked a question before and somebody give me a guide and I read it and I saw this
var temp = setTimeout,
setTimeout = function() {};
He said that temp will be undefined due to JavaScript hoisting and I dont understand why
Its not should be like that?
var temp;
temp = setTimeout;
setTimeout = function() {};
so why its undefined?

This is not the same. Your multiple var declaration also declares setTimeout:
var temp = setTimeout,
setTimeout = function() {};
which is hoisted to
var temp; // = undefined
var setTimeout; // = undefined
temp = setTimeout;
setTimeout = function() {};

The scope of a variable declared with the keyword var is its current execution context. When a variable is initialized, javascript engine by default initializes the variable to undefined.
Like,
var a; //it initializes to undefined
Again when you use a variable before declaring them, its now on running context.
For Example:
console.log(a);
var a=10;
in this case, javascript engine runs the code in following ways,
var a; // a = undefined
console.log(a); //
a =10;
it pick up the variable declaration to the top of the execution context but not its value. This is called hoisting that you have already probably known.
In your case:
var temp = setTimeout,
setTimeout = function() {};
from function(){}, suppose we get value =10;
now your code seems like:
var temp = setTimeout,
setTimeout = 10;
but javascript does the thing in the following way,
var temp; // temp = undefined
var setTimeout; // setTimeout = undefined
temp = setTimeout; // here temp is undefined as setTimeout is undefined
setTimeout =10;
it keep up all declared variable to the top of stack (Not its value but initializes to undefined).
If you want to learn more, visit the following link:
medium: what is javascript hoisting
scotch: understand hoisting in javascript

Related

Does Var variables get hoisted out of the IIFE? [duplicate]

This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 1 year ago.
I have a block of code and I want to exactly know the running order and why the result like this:
var variable = 10;
(()=>{
variable_3 = 35;
console.log(variable_3);
var variable_3 = 45;
variable_2 = 15;
console.log(variable);
})();
console.log(variable_2);
console.log(variable_3);
var variable=30;
The output for this code is
35, 10, 15, Error
What I understand is:
inside the IIFE we create a global variable_3 and assigned 35.
Then it print out 35.
We create a Var variable_3 inside the IIFE and assigned 45. (Is this Var get hoisted out of the IIFE??)
35.10.15 I understand, can you explain the last number and make my logic correct?
Thanks!
(()=> {
a = 123;
console.log(a); // 123
console.log(window.a); // undefined
var a;
})();
(()=>{
var a = 4;
(()=>{
console.log(a); // undefined
var a = 5;
})()
})()
(()=>{
var source = {};
(()=>{
a = source;
var a;
console.log(a === source) // true
// The variable source is indeed assigned to variable a, although variable a is declared after
})()
})()
var variable is a definition
like function ,
function can use before defined;
main();
function main(){}
so
a = 1;
var a;
like function; use variable before define is also ok;
1.)Basically there are two scopes, that is the local and global scope. The function
scope falls within the local scope.
2.)Hoisting moves declarations to the top of the current scope.
3.)If you assign a value to a variable you have not previously declared, it is automatically declared as a global variable(even if it is within a function) and initialized with the assigned value.
4.)In the local function scope, declaring with var, let or const keywords will all create a local variable. It is only available or accessible within that function.
In your case:
var variable = 10;//global variable declaration, outside the function.
(()=>{
variable_3 = 35;//declares a global variable, ref. (3).
console.log(variable_3);//prints 35, because it is available globally now.
var variable_3 = 45;//re-declaration turns it to local variable, ref. (4).
variable_2 = 15;//declares global variable, ref. (3)
console.log(variable);//prints 10, because it is a global variable.
})();
console.log(variable_2);//prints because it is a global variable
console.log(variable_3);//fail to print because of re-declaration which changed it from a global variable to local function variable.
var variable=30;

Understanding JavaScript Closures with a small example

I am trying to get around understanding javascript closures from a practical scenario.I know from a theoretical perspective , With the help of closures inner functions can have access to the variables in the enclosing function i.e parent function.
I have read a couple of questions on stackOverflow as well.
i am really missing the point of what is happening here?
var foo = [];
for(var i=0;i<10;i++){
foo[i] = function(){
return i;
}
}
console.log(foo[0]());
This gives me out a 10. Most of the articles say that by the time it reaches the inner anonymous function, The for loop is getting executed as a result the last value that is present in the loop which is 10 is being printed.
But i am still not able to get to the bottom of this.
On Contrary, If i use something like:
var foo = [];
for(var i=0;i<10;i++){
(function(){
var y =i;
foo[i] = function(){
return y;
}
})();
}
console.log(foo[0]());
I am getting the output.Any help would be highly appreciated.
maybe this code block helps
var foo = [];
for(var i = 0; i < 10; i++) {
foo[i] = function() {
return i; // is a reference and will always be the value, which 'i' have on function execution
}
}
// 'i' is 10 here!
console.log(foo[0]()); // executing the function will return the current value of 'i'
///////////////////////////////////////
var foo = [];
for(var i=0;i<10;i++) {
/* thats a IIFE (immediately invoked function expression) */
(function(a) { // 'a' is now a local variable
foo[a] = function() { // defines a function
return a; // is a reference to local variable 'a'
};
})(i); // <- passing the current value of i as parameter to the invoked function
}
// 'i' is 10 here
console.log(foo[0]()); // returns the reference to 'a' within the same scope, where the function was defined
In your first scenario, all of your functions added to the foo array are referencing the same var i. All functions will return whatever i was set to last, which is 10 because during the last iteration of the loop that's what it's value was set to.
In the second scenario, you are Immediately Invoking this function:
(function(){
var y =i;
foo[i] = function(){
return y;
}
})();
By immediately invoking it you are effectively locking in the local state of var y, for each iteration of the loop - it provides a unique scope for each function added to the array.

Vanilla JS | Invokable object that also contains property

I was asked in some assignment to do the following:
fun4(): returns a object that can be invoked as a function. this object should also has a ‘k’ property with null value ( so fun4()() should do something)
The first part of the question is easy and understandable.
The second one is the issue for me.
How can I create an object in JS that can be invoked and accessed statically.
To simplify:
Can one create an object that behaves as follows:
> let o = CustomObject;
> o.k
< null
> o()
< //Some value returned here from the function
Thanks!
It looks very straightforward to me...
let CustomObject = function(){ return "hello"; }
CustomObject.k = null;
This will pass your Acceptance criteria
As for vanilla js, this is what you are looking for:
var fun4 = function () {
let val = function () { console.log("hello"); };
val.k = null;
return val;
}
fun4() // returns the function
fun4()() // logs 'hello'
fun4().k // returns null
Given one of your comments above, one thing to watch out for is your use of let and var. In this case, var could be used instead without any difference (when val falls out of scope when the function returns, the variable will be released for garbage collection). However, when you are running this within the console (and when not inside a function or other well-defined and isolated scope), variables created using let will get destroyed after every invocation -- in other words, whenever you press return. The way to demonstrate this is to compare these:
var test = function () {
let x = 1;
let x = 1; // this will cause an immediate syntax error when the script is parsed;
}
On the other hand:
> let x = 1;
< undefined
> let x = 1; // In the console, this will not raise any error/exception
// because the scope is cleared after the line above has
// executed and returned
< undefined
You can see a 'k' property as below.

Why is no ReferenceError being thrown if a variable is used before it’s declared?

I’m trying to wrap my head around the behavior of reference errors thrown in JavaScript.
In the following example, a ReferenceError is thrown at the second line, and execution breaks:
var obj = {};
obj.func1 = func2;
alert('Completed');
Whereas in this example, the code completes successfully, though obj.func1 remains undefined:
var obj = {};
obj.func1 = func2;
var func2 = function() {
alert('func2');
};
alert('Completed');
My assumption was that an error would be thrown at the second line just the same, and when that wasn’t the case, I’d have expected obj.func1 to properly reference func2, but I’ve been double blind-sided. So what exactly is going on here?
This is due to Javascript variable declaration "hoisting".
A variable declared with var is visible everywhere in the function, so there's no Reference Error. However, it doesn't actually receive its value until you execute the statement that initializes it. So your second example is equivalent to:
var func2;
var obj = {};
obj.func1 = func2;
func2 = function() {
alert('func2');
};
alert('Completed');
In this rewrite, you can see that the variable exists when you perform the assignment to obj.func1. But since it doesn't yet have a value, you assign undefined to obj.func1. Assigning to func2 later doesn't change that.
var is hoisted; the variable exists throughout the current scope. Thus, the second example is equivalent to:
var obj;
var func2;
obj = {};
obj.func1 = func2;
func2 = function() {
alert('func2');
}
alert('Completed');
Thus, when you do the assignment, The name func2 is known, but undefined. In the first example, it is unknown, which raises ReferenceError.
Your func2 variable is not visible. That's why obj.func1 remains undefined.
var obj = {};
var func2 = function() {
alert('func2');
return "Test";
};
obj.func1 = func2;
alert('Completed');

JavaScript: Initializing inner variable after initializing object

Update: rewriting question because original question had false assumptions (I was running code in a console that had already initialized the variables I thought were undefined).
This makes sense:
var obj = { 'whichScope': a };
obj.whichScope; //"ReferenceError: a is not defined"
But then how come this next example doesn't throw an error? And if the second line is getting run before the first line, why doesn't obj.whichScope resolve to "After"?
var obj = { 'whichScope': a };
var a = "After";
obj.whichScope; //"undefined"
If "var a" in the previous example runs before obj is initialized, does any part of 'a = "After";' also run before obj is initialized?
var a = "Before";
var obj = { 'whichScope': a };
a = "After";
obj.whichScope; //"Before"
If whichScope refers to a function that returns 'a' then it does resolve to "After" in the last example.
That is called variable hoisting.
References:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/var#var_hoisting
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/
Variables (declared with var) and functions are hoisted to the top of their scope.
So technically, your script is like this:
var a; // = undefined
var obj = { 'whichScope': a };
a = "After";
Although your first example doesn't do what you say. The value of obj.whichScope is undefined, as expected.
DEMO: http://jsfiddle.net/pRQwK/
As for your last statement, If whichScope refers to a function that returns 'a' then it does resolve to "After" in the second example. - that is because the value of a isn't captured (by a closure). When setting a property, its value is captured immediately (unrelated to a closure).

Categories

Resources