http://javascript.info/var
https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75
var has no block scope
var variables are either function-wide or global, they are visible through blocks.
For instance:
1 2 3 4 |
if (true) { var test = true; // use "var" instead of "let" } alert(test); // true, the variable lives after if |
If we used let test on the 2nd line, then it wouldn’t be visible to alert. But var ignores code blocks, so we’ve got a global test.
var HAS function scope
1 2 3 4 5 6 7 |
function sayHi() { var phrase = "Hello"; // local variable, "var" instead of "let" alert(phrase); // Hello } sayHi(); alert(phrase); // Error, phrase is not defined |
var cannot be block- or loop-local
1 2 3 4 |
for(var i = 0; i < 10; i++) { // ... } alert(i); // 10, "i" is visible after loop, it's a global variable |
vars are processed at the function start
var declarations are processed when the function starts (or script starts for globals).
In other words, var variables are defined from the beginning of the function, no matter where the definition is (assuming that the definition is not in the nested function).
So this code:
1 2 3 4 5 |
function sayHi() { phrase = "Hello"; alert(phrase); var phrase; } |
is same as:
1 2 3 4 5 |
function sayHi() { var phrase; phrase = "Hello"; alert(phrase); } |
..and same as this:
1 2 3 4 5 6 7 8 9 |
function sayHi() { phrase = "Hello"; // (*) if (false) { var phrase; } alert(phrase); } |
People also call such behavior “hoisting” (raising), because all var are “hoisted” (raised) to the top of the function.
So in the example above, if (false) branch never executes, but that doesn’t matter. The var inside it is processed in the beginning of the function, so at the moment of (*) the variable exists.
Assignments are not hoisted
1 2 3 4 5 6 |
function sayHi() { var phrase; // declaration works at the start... alert(phrase); // undefined phrase = "Hello"; // ...assignment - when the execution reaches it. } sayHi(); |
Because all var declarations are processed at the function start, we can reference them at any place. But variables are undefined until the assignments.
In both examples above alert runs without an error, because the variable phrase exists. But its value is not yet assigned, so it shows undefined.
Let
let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope. An explanation of why the name “let” was chosen can be found here.
up vote
3526
down vote
accepted
The difference is scoping. var is scoped to the nearest function block and let is scoped to the nearest enclosing block, which can be smaller than a function block. Both are global if outside any block.
Also, variables declared with let are not accessible before they are declared in their enclosing block. As seen in the demo, this will throw a ReferenceError exception.
Block Visibility
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function allyIlliterate() { //tuce is NOT visible out here for( let tuce = 0; tuce < 5; tuce++ ) { //tuce is only visible in here (and in the for() parentheses) //and there is a separate tuce variable for each iteration of the loop } //tuce is NOT visible out here } function byE40() { //nish *is* visible out here for( var nish = 0; nish < 5; nish++ ) { } //nish *is* visible out here } |
Redeclaration
Assuming strict mode, var will let you re-declare the same variable in the same scope. On the other hand, let will not:
1 2 3 4 5 6 7 |
'use strict'; let me = 'foo'; let me = 'bar'; // SyntaxError: Identifier 'me' has already been declared 'use strict'; var me = 'foo'; var me = 'bar'; // No problem, `me` is replaced. |
Global
They are very similar when used like this outside a function block.
1 2 3 4 5 6 7 8 9 |
let me = 'go'; // globally scoped var i = 'able'; // globally scoped // However, global variables defined with let will not be added // as properties on the global window object like those // defined with var. console.log(window.me); // undefined console.log(window.i); // 'able' |
More Examples
When using var, and there’s no function enclosed, the variable gets globally scoped. In other words, by definition,
var are function scoped. But since there is no function, it gets globally scoped.
1 2 3 4 5 6 7 |
var age = 100; if(age > 12) { var dogYears = age * 7; console.log(`You are ${dogYears} dog years old!`); } // age is valid here |
let is blocked something
Any time you see a curly bracket, its a block. Functions are also blocks. Let and const are still going to be scoped to a function, but if inside of that function or if inside some other element that you have, it will be scoped to the closest set of curly brackets.
1 2 3 4 5 6 |
var age = 100; if(age > 12) { let dogYears = age * 7; console.log(`You are ${dogYears} dog years old!`); } console.log(dogYears); // error because it's scoped only to the above block |
const
const is the same as let, the difference lies in that const cannot be reassigned. Let can.
However, keep in mind that properties of const can be reassigned.
const is a signal that the identifier won’t be reassigned.
let is a signal that the variable may be reassigned. i.e counter in a loop, value swap in algorithm.
It also signals that the variable will be used only in the block it’s defined in.
var is now the weakest signal available because it may or may not be reassigned. The variable may
or may not be used for an entire function, or just for the purpose of a block or loop.