Why JavaScript cannot hoist initialization? [duplicate] - javascript

This question already has answers here:
Hoisting variables in JavaScript
(5 answers)
Closed 1 year ago.
I am studying hoisting concept now, but i cannot understand why
hoisting can only work on declaration, not initialization.
declaration O
catName("cat");
function catName(name){
console.log(name) // return cat
}
initialization X
console.log(num); // return undefined
var num;
num = 6;

...why hoisting can only work on declaration, not initialization
It can work with initialization (and in fact, that var variable is initialized — with the value undefined), it's just that hoisting the initializer expression is not defined for var. Hoisting initialization is defined for function declarations: The binding (loosely, variable) for the function is both declared and initialized with the function object:
console.log(example); // Shows the function
function example() {
}
It's just that that's not how var is defined, not least because hoisting the initialization expression (rather than undefined) would be much more complicated than hoisting the initialization of a function identifier, because var initializers can be any arbitrary expression. So instead, var variables are initialized with undefined.
Fast-forward several years and the initialization of let, const, and class aren't hoisted at all (only the declaration), leading us to the Temporal Dead Zone between declaration and initialization during which you can't access them, because that was deemed more useful than hoisting undefined:
console.log(example); // ReferenceError
let example = 42;

Related

JavaScript hoisting confusion regarding let [duplicate]

This question already has answers here:
What is the temporal dead zone?
(3 answers)
Closed 2 years ago.
a= 10; console.log(a); let a; => Cannot access 'a' before initialization
above code gives error for initialization, even if a is declared before use. Please explain how this gives an error if a is already hoisted and get declared "a=10" before using it.
That also means if a variable is declared with let or const, hoisting doesn't have any practical impact ?
if I run below code
let a; console.log(a); => undefined
in this case I am able to print a i.e. undefined, without initializing it.
What is happening in core ?
When you type:
a=10
then you are defining a global variable. It is deprecated and not recommended style of coding in almost all languages.
To prevent declaring global variables es6 introduced let and const.
Now when you are using let or const your interpreter checks that when you typing
let a;
you do not have a used before this declaration. This is the reason for the error.
Update:
You typed:
let a; console.log(a); => undefined
it is ok because a is declared, memory is reserved, the symbol a is registered, but the value is not assigned, so when you evaluate the value assigned to symbol a it is undefined.
Please compare it with case:
console.log(c);
You will get an error:
Uncaught ReferenceError: c is not defined
because the symbol c was never declared.
Now when you will assign values to a it will be done in local scope, but when you will assign values to c it will create global variables.
To improve your understanding please read about all methods of defining variables and look at all edge cases. A great article is under the link:
https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/

Why there is "not a function" error if calling a function before function declaration with es6 syntax? [duplicate]

This question already has answers here:
Javascript function scoping and hoisting
(18 answers)
Are variables declared with let or const hoisted?
(7 answers)
Closed 3 years ago.
Using older syntax
Prints "this is myfunc1"
myfunc1();
function myfunc1() {
console.log("this is myfunc1");
}
Using es6 syntax
This gives error "myfunc2 is not a function"
myfunc2();
var myfunc2 = () => {
console.log("this is myfunc2");
}
Function declarations are hoisted.
Variable declarations using var keyword are also hoisted (meaning the Javascript engine "knows" the variable has been declared) but, because assignments are not hoisted, the variable will contain undefined until the line of code that does the assignment is executed.
Do not consider this "old" and "new" syntax.
Function declarations, function expressions, and arrow functions all have different behaviour. While arrow functions were introduced to the language more recently, they are not a replacement for function declarations or function expressions.

Function declarations and variable declarations hoisted, which one hoisted first? [duplicate]

This question already has answers here:
Order of hoisting in JavaScript
(2 answers)
Closed 6 years ago.
I came to know 'Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter.' -- JavaScript Scoping and Hoisting.
But which one hoisted first?
As a result of someone asked me at SegmentFault, I should give him a exact answer.
function test() {
return foo;
var foo = true;
function foo(){}
}
console.log(typeof test()) // function
functions are hoisted first
See here for more informations

Understanding let vs. var hoisting [duplicate]

This question already has answers here:
Are variables declared with let or const hoisted?
(7 answers)
Closed 6 years ago.
With let vs. var I've learned that the major difference is that let variables are scoped to the nearest block and are not hoisted. Also let variables can be reassigned but cannot be redeclared within the same scope. Why then does this code return a "not defined" error?
let x = 10;
if (true) {
console.log(x);
let x = 11;
}
returns:
Uncaught ReferenceError: x is not defined(…)
While:
let x = 10;
if (true) {
console.log(x);
}
logs 10 without an error?
The main difference between var and let is that:
var is hoisted to the wrapping function block.
let is hoisted to the wrapping {} block
The second code sample doesn't have the same reference conflict as the first because you're declaring x prior to referencing it in the following if block.
EDIT To address Pointy's comment below:
You're experiencing the ReferenceError because of the temporal dead zone
If you reference a variable defined by let within the same block before it is defined you will receive this error.
From MDN let Docs
In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.
function do_something() {
console.log(foo); // ReferenceError
let foo = 2;
}
let variables are actually hoisted (within the block). From MDN:
In ECMAScript 2015, let will hoist the variable to the top of the block.

Named function expression [duplicate]

This question already has answers here:
Why JavaScript function declaration (and expression)?
(5 answers)
Closed 8 years ago.
I'm assigning a named function expression to a property of an object:
var foo = {};
foo.bar = function bar(){
console.log('bar');
};
foo.bar() => bar
bar() => ReferenceError: bar is not defined
Why can't I call bar() directly, why isn't it defined?
I know that I can simply chain the assignment like var bar = foo.bar = function(){}, so I'm not looking for a work-around or other solution, I'm only interested in why it doesn't work.
I've tested in Chrome console and Node.JS.
Named function expressions are simply not supposed to work that way. The function name is only visible inside the function, not outside.
A function instantiation expression that happens to have a name is not the same thing as a function declaration statement. Those are two distinct syntactic (and semantic) entities in the language.

Categories

Resources