0

(1) why are the two examples different?

console.log(a); 
a = 1; // this will have a is not defined;
console.log(a); 
function a(){}; // this will have no error;

(2)In browser console.

console.log(a); 
a = 1; 
window.a === 1; // true   

why is the variable a bound to window but console.log still has an error.

window.a = 1;
console.log(a);

why is the variable a bound to window but console.log has no error.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
JackieWillen
  • 673
  • 1
  • 12
  • 23
  • 1
    This isn't limited to the console - that's how normal JavaScript works – VLAZ Jul 15 '20 at 12:24
  • Of all your examples, only the second one with `function a() {}` has hoisting. None of the other examples employ variable hoisting because [they don't have variables](https://stackoverflow.com/questions/1470488/what-is-the-purpose-of-the-var-keyword-and-when-should-i-use-it-or-omit-it) which is exactly why you get a problem. Without hoisting you cannot access an identifier before it's declared. – VLAZ Jul 15 '20 at 12:34
  • `function` declarations are hoisted. – Unmitigated Jul 15 '20 at 12:35

3 Answers3

3

the first example console.log(a); a = 1; will return an error because your variable is not declared and only declared variables are hoisted using a keyword such as var for example

From MDN

JavaScript only hoists declarations, not initializations. If a variable is declared and initialized after using it, the value will be undefined.

The ex console.log(a); function a(){}; doesn't return an error because JavaScript is adding the function declarations to memory before it executes aka Hoisting

in the example console.log(a); a = 1; window.a === 1; will return an error because your variable is not declared, same as the first example

in this example window.a = 1; console.log(a)won't return an error because you added the variable to the global object window and gave it a value of 1 before attempting to print it's value.

Sven.hig
  • 4,449
  • 2
  • 8
  • 18
  • in the last example. window.a = 1; console.log(a).a will find value from window.a. why console.log(a); a = 1; the console will not find a from window while the window.a is undefined, so the result is undefined not an error. – JackieWillen Jul 15 '20 at 12:49
  • @JackieWillen if your run console.log(a); a = 1 you get this message "Uncaught ReferenceError: a is not defined" it's an error basically telling you a is not defined – Sven.hig Jul 15 '20 at 12:53
  • `console.log(a); a = 1` will return an error because a is initialized but not declared and only declared variables using a keyword such as `var` for example will be hoisted does that makes since ? – Sven.hig Jul 15 '20 at 12:57
  • Problem is on console.log(a); 'a' get it's value from window. When window.a=1 console.log(a) will return '1'.Why console.log(a) will not print 'undefined' while window.a is indeed 'undefined' – JackieWillen Jul 15 '20 at 13:01
  • because `console.log(a); a = 1` you are trying to print the value before JS gives it a reference in memory (_before JS knows about it's value from memory_) and `window.a = 1; console.log(a)` you first told JS the value of `a` and then you print the value (_JS will be able to print the value of a and not undefined because he has reference to the variable a with value 1 in memory_) – Sven.hig Jul 15 '20 at 13:06
  • Thank you.But console.log(window.a); a=1; will print 'undefined' While console.log(a); a=1; will print error. They are not same? – JackieWillen Jul 15 '20 at 13:17
  • No they are not the same because the global variable `window` exist already and what you are doing by console(window.a) you are telling JS in plain english _go to `window` object and check for variable `a` if it's there and print it in console_ and since there is no variable `a` in window it returns `undefined` – Sven.hig Jul 15 '20 at 13:21
1

This is called hoisting in javascript.

(1)

console.log(a); 
a = 1; // this will have a is not defined;

In the above snippet, a is assigned after console, so it is throwing an error.

In case if you have

 console.log(a);
 var a = 1;

The result will be undefined printed in the console. It is because of hoisting. Javascript will execute the above in the following order.

var a;
console.log(a);
a = 1;

Hoisting is executing the initialisation first and rest of the execution will go as per the flow.

var a; is executed first and a is initialized to the scope. Hence console.log(a) will not throw any error. At the time of its execution, a value is undefined.

(2)

console.log(a); 
a = 1; 
window.a === 1; // true   

Whenever you try to do anything in the console, all the variables and functions will be registered with the window scope. So, when you do a = 1 in console, it will be window.a.

(3)

console.log(a); 
function a(){}; // this will have no error;

The same hoisting applies to functions also. When you created a function using constructor like above, it will be hoisted. If you execute the below snippet you will get error because it is not hoisted.

console.log(a)
a = function(){}

why is the variable a bound to window but console.log still has an error.

The variable is registered with window scope, but it is not hoisted. So you will get error. Hoisting will only work when you initialize a variable.

To get further details about hoisting, feel free to read docs

Stark Buttowski
  • 1,799
  • 2
  • 10
  • 21
  • "*In the above snippet, a is declared after console*" it's **not** declared, it's only assigned. Implicit assignment to global objects are not counted as declarations. – VLAZ Jul 15 '20 at 14:03
  • "*If you do the below snippet you will get error as it is not hoisted.*" [`let` and `const` variables **are** hoisted](https://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-hoisted) however you're running into the temporal dead zone. TDZ can *only* exist if the declaration is hoisted, so the environment will know that the binding is "reserved" but not usable *yet*, hence you'd get a different error than just the identifier being *unusable* (e.g., trying to read an undeclared variable) – VLAZ Jul 15 '20 at 14:06
0
console.log(a);  a = 1; // this will have a is not defined;
console.log(a);  function a(){}; // this will have no error;

The function keyword is bound before any code will be excuted in JS.

console.log(a); 
a = 1; 
window.a === 1; // true 

why is the variable a bound to window but console.log still has an error.

window.a = 1;
console.log(a);

why is the variable a bound to window but console.log has no error.

You're already in the window context. So a is the same as window.a.

alexP
  • 3,672
  • 7
  • 27
  • 36