A solution to ‘var self = this’
A common situation in javascript is needing to access a property or method of the parent scope object within a closure. To solve this, we declare a variable referencing the parent scope, and then access the desired property or method using that variable within our closure. Consider this example:
class Pizza {
constructor(name toppings) {
this.name = name;
this.toppings = toppings;
this.availableMeats = ['Chicken', 'Pepperoni'];
}
getMeatToppings() {
var self = this;
return this.toppings.filter(function(topping){
return (self.availableMeats.indexOf(topping) > -1);
});
}
}
Notice the var self = this in the Pizza.getMeatToppings method. ES6 introduces a way to declare functions that don’t create an isolate scope. You can declare a method using an arrow function instead of the function keyword:
class Pizza {
constructor(name toppings) {
this.name = name;
this.toppings = toppings;
this.availableMeats = ['Chicken', 'Pepperoni'];
}
getMeatToppings() {
return this.toppings.filter((topping)=>;{
return (this.availableMeats.indexOf(topping) > -1);
});
}
}
Notice the way Pizza.getMeatToppings() is declared with => instead of function. This new syntax is called an arrow function.
Block scope in ES6
Variables in ES5 can be in two scopes — function scope or global scope. ES6 introduces a new way to declare variables in block scope using the let keyword.
getData().then(function(response){
if (response.status == 'OK') {
var data = response.data;
/* do stuff with data */
}
});
In the example above, the data variable is often treated as if it its scope is the if block — when the variable is actually function scoped. The actual scope looks something like this:
getData().then(function(response){
var data = undefined;
if (response.status == 'OK') {
data = response.data;
/* do stuff with data */
}
});
This is called hoisting. When a variable is declared, the declaration is ‘hoisted’ to the top of the current scope.
Declaring block scoped variables with let
ES6 introduces a new way to define variables using the let keyword instead of var. Variables declared with var are function scoped — and variables declared with let are block scoped. We can revise the above example to make the data variable scoped to the if block, by using the let keyword:
getData().then(function(response){
if (response.status == 'OK') {
let data = response.data;
/* do stuff with data */
}
});
In the revised code, the data variable is scoped to the if block. The let keyword can be used to bind variables to the scope of a for loop:
for (let i = 0; i < 10; i++) {
console.log(i); // > 1, 2 ... 9, 10
}
console.log(i); // > undefined
Declaring constants with const
Another new keyword for variable declaration in ES6 is const. Variables declared with const represent a constant reference to a value. The value being referenced may changed, but the value cannot be reassigned. Here’s an example:
const languages = ['English', 'Spanish'];
data.push('French');
console.log(data); // > ['English', 'Spanish', 'French'];
The above example will print out the languages array, including the item we pushed. If we try to assign the constant to a new array, an error is thrown:
const languages = ['English', 'Spanish']; languages = []; // -> Error
There’s a lot of confusion surrounding scope in javascript. With the advancements brought by ES6, scoping will become more manageable.


