Block Scope

This section we will dive into new features in JavaScript.

One thing that many JavaScript developer didn’t realize is that the default scope of variable in JavaScript is function:

js
function add() {
var a = 2;
var b = 5;
return a + b;
}
// console.log(a); // a is not accessible here
function addIfTrue(isTrue, times) {
var x = 5;
if (isTrue) {
var tmp = x * times;
x = x + tmp;
}
console.log(`tmp: ${tmp}`); // but tmp is accessible here
return x;
}
console.log(`add: ${add()}`);
console.log(`addIfTrue: ${addIfTrue(true, 2)}`);
js
function add() {
var a = 2;
var b = 5;
return a + b;
}
// console.log(a); // a is not accessible here
function addIfTrue(isTrue, times) {
var x = 5;
if (isTrue) {
var tmp = x * times;
x = x + tmp;
}
console.log(`tmp: ${tmp}`); // but tmp is accessible here
return x;
}
console.log(`add: ${add()}`);
console.log(`addIfTrue: ${addIfTrue(true, 2)}`);

This is in contrast with most programming languages like Java or C in which the scope of the variable is block (the closest curly braces pair {}).

This behavior applies for for loop as well:

js
var y = 0;
for (var x = 0; x < 5; x++) {
y += x;
}
console.log(y); // 10
console.log(x); // 5, because x is not scoped within the for loop
js
var y = 0;
for (var x = 0; x < 5; x++) {
y += x;
}
console.log(y); // 10
console.log(x); // 5, because x is not scoped within the for loop

Now JavaScript has two new keywords, let and const, which will scoped within the block.

js
function addIfTrue(isTrue, times) {
var x = 5;
if (isTrue) {
let tmp = x * times;
x = x + tmp;
}
// console.log(`tmp: ${tmp}`); // tmp is not accessible here
return x;
}
var y = 0;
for (let x = 0; x < 5; x++) {
y += x;
}
console.log(y); // 10
// console.log(x); // x is not accessible here
console.log(`addIfTrue: ${addIfTrue(true, 2)}`);
js
function addIfTrue(isTrue, times) {
var x = 5;
if (isTrue) {
let tmp = x * times;
x = x + tmp;
}
// console.log(`tmp: ${tmp}`); // tmp is not accessible here
return x;
}
var y = 0;
for (let x = 0; x < 5; x++) {
y += x;
}
console.log(y); // 10
// console.log(x); // x is not accessible here
console.log(`addIfTrue: ${addIfTrue(true, 2)}`);

const behaves like let, but it cannot be reassigned.

js
let x = 5;
x = 15; // OK
const y = 10;
// y = 15; // Error
js
let x = 5;
x = 15; // OK
const y = 10;
// y = 15; // Error

Today, most JavaScript developers use const by default, and switch to let when they need to reassign the variable. Very few developer use var anymore.

Note that const cannot be reassigned doesn’t mean it cannot be changed. If the variable is not a primitive value, i.e. boolean, string, or number, it could be modified.

js
const x = 5; // primitive, you can expect x will always be 5;
const y = []; // not primitive, you may expect it will always be an empty array
y.push(5); // this is fine for JavaScript, because it is not reassigned
y.push(10);
console.log(y); // [5]
js
const x = 5; // primitive, you can expect x will always be 5;
const y = []; // not primitive, you may expect it will always be an empty array
y.push(5); // this is fine for JavaScript, because it is not reassigned
y.push(10);
console.log(y); // [5]