Part One
Understand what ES2015 is and how the term came to be
Refactor code to use let and const and explain the implications of using both
1995 + 1996
1997
1998
1999
2009
2015
2016
2017
Start
ES1
ES2
ES3
ES5
ES6 / ES2015
ES
2016
ES
2017
var firstInstructor = "Colt";
firstInstructor = "Elie"; // no problem here
const anotherInstructor = "Tim";
anotherInstructor = "Elie"; // TypeError
const anotherInstructor = "Elie"; // SyntaxError
const numbers = [1,2,3,4];
numbers.push(10); // 5
numbers; // [1,2,3,4,5]
numbers = "no!"; // TypeError
Can mutate if it is an object, but not declare again
let anotherInstructor = "Tim";
anotherInstructor = "Elie"; // no problems here!
let anotherInstructor = "Tim"; // SyntaxError
Can reassign, can not redeclare
var instructor = "Elie";
if(instructor === "Elie"){
let funFact = "Plays the cello";
}
funFact; // ReferenceError!
blocks create scope!
function helloInstructor(){
return elie;
var elie = "ME!";
}
helloInstructor(); // undefined
let does hoist, but we can not access the value - it is in a TDZ (Temporal Dead Zone)
function helloSecondInstructor(){
return colt;
let colt = "HIM!";
}
helloSecondInstructor(); // ReferenceError
for(var i = 0; i < 5; i++){
setTimeout(function(){
console.log(i);
},1000)
}
// 5 (five times)
for(var i = 0; i < 5; i++){
(function(j){
setTimeout(function(){
console.log(j);
},1000);
})(i)
}
// 0
// 1
// 2
// 3
// 4
for(let i = 0; i < 5; i++){
setTimeout(function(){
console.log(i);
},1000);
}
// 0
// 1
// 2
// 3
// 4
var firstName = "Elie";
var lastName = "Schoppik";
console.log("Hello " + firstName + " " + lastName); // error prone!
Make sure you use backticks!
console.log(`Hello ${firstName} ${lastName}`); // Much nicer!
"
Hello
" // does not work!
`
Hello
How
Nice
Is
This!
` // works well!
// ES5
var add = function(a,b){
return a+b;
}
// ES2015
var add = (a,b) => {
return a+b;
}
Replace the keyword 'function' with =>
Just the start...
var add = (a,b) => {
return a+b;
}
We can go from:
var add = (a,b) => a+b;
To:
// ES5
[1,2,3].map(function(value){
return value * 2;
}); // [2,4,6]
// ES2015
[1,2,3].map(value => value * 2); // [2,4,6];
We can go from:
To:
function doubleAndFilter(arr){
return arr.map(function(value){
return value * 2;
}).filter(function(value){
return value % 3 === 0;
})
};
doubleAndFilter([5,10,15,20]); // [30]
var doubleAndFilter = arr => arr.map(val => val * 2).filter(num => num % 3 === 0);
doubleAndFilter([5,10,15,20]); // [30]
Notice that if we only have one parameter, we do not need parenthesis around it with arrow functions!
We can go from:
To:
var instructor = {
firstName: "Elie",
sayHi: function(){
setTimeout(function(){
console.log("Hello " + this.firstName);
}, 1000);
}
}
var instructor = {
firstName: "Elie",
sayHi: function(){
setTimeout(function(){
console.log("Hello " + this.firstName);
}.bind(this), 1000);
}
}
instructor.sayHi(); // "Hello undefined"
instructor.sayHi(); // "Hello Elie"
var instructor = {
firstName: "Elie",
sayHi: function(){
setTimeout(() => {
console.log("Hello " + this.firstName);
}, 1000);
}
}
instructor.sayHi(); // "Hello Elie"
Arrow functions do not have their own keyword this. The keyword this refers to its enclosing context (the instructor object).
But why does this work?
var instructor = {
firstName: "Elie",
// why can't we use an arrow function here?
sayHi: function(){
setTimeout(() => {
console.log("Hello " + this.firstName);
}, 1000);
}
}
instructor.sayHi(); // "Hello Elie"
If we use an arrow function, the sayHi function will not have its own keyword this - and the keyword this will not refer to the instructor object anymore!
We used both the function keyword and an arrow function - why?
var add = (a,b) => {
return arguments;
}
add(2,4); // ReferenceError: arguments is not defined
arrow functions do not get their own keyword arguments
An arguments keyword can be accessed if the arrow function is inside of another function (it will be the outer functions arguments)
function outer() {
return innerFunction = () => {
return arguments;
}
}
outer(1)(2); // only prints out [1]
If you REALLY need the arguments to an arrow function, use the rest operator - we'll see that very soon!
var instructor = {
firstName: "Elie",
sayHi: () => `Hello ${this.firstName}`;
}
instructor.sayHi(); // "Hello undefined"
Arrow functions should NEVER be used as methods in objects since we will get the incorrect value of the keyword this. ES2015 provides a better alternative - we'll see it soon!
function add(a, b){
return a+b;
}
add(); // NaN because a is undefined and b is undefined
function add(a=10, b=20){
return a+b;
}
add(); // 30
add(20); // 40
var arr = [1,2,3,4,5];
for(let val of arr){
console.log(val);
}
// 1
// 2
// 3
// 4
// 5
function printRest(a,b,...c){
console.log(a);
console.log(b);
console.log(c);
}
printRest(1,2,3,4,5);
// 1
// 2
// [3,4,5]
// ES5
function sumArguments(){
var total = 0;
for(var i = 0; i < arguments.length; i++){
total += arguments[i];
}
return total;
}
// ES2015
var sumArguments = (...args) => args.reduce((acc, next) => acc + next);
// A little fancier ES5
function sumArguments(){
var argumentsArray = [].slice.call(arguments);
return argumentsArray.reduce(function(accumulator,nextValue){
return accumulator + nextValue;
});
}
// ES5
var arr1 = [1,2,3];
var arr2 = [4,5,6];
var arr3 = [7,8,9];
var combined = arr1.concat(arr2).concat(arr3);
// ES2015
var combined = [...arr1, ...arr2, ...arr3];
// ES2015
Math.max(...arr); // 5
var arr = [3,2,4,1,5];
Math.max(arr); // NaN
// ES5
Math.max.apply(this, arr); // 5
function sumValues(a,b,c){
return a+b+c;
}
var nums = [12,15,20];
// ES2015
sumValues(...nums); // 47
// ES5
sumValues.apply(this, nums); // 47
var firstName = "Elie";
var lastName = "Schoppik";
// ES5
var instructor = {
firstName: firstName,
lastName: lastName
}
var firstName = "Elie";
var lastName = "Schoppik";
// ES2015
var instructor = {
firstName,
lastName
}
// ES5
var instructor = {
sayHello: function(){
return "Hello!";
}
}
// ES2015 - do NOT use arrow functions here!
var instructor = {
sayHello(){
return "Hello!";
}
}
// ES5
var firstName = "Elie";
var instructor = {};
instructor[firstName] = "That's me!";
instructor.Elie; // "That's me!"
// ES2015
var firstName = "Elie";
var instructor = {
[firstName]: "That's me!"
}
instructor.Elie; // "That's me!"
Extracting values from data stored in objects and arrays
var instructor = {
firstName: "Elie",
lastName: "Schoppik"
}
var firstName = instructor.firstName;
var lastName = instructor.lastName;
firstName; // "Elie"
lastName; // "Schoppik"
var instructor = {
firstName: "Elie",
lastName: "Schoppik"
}
var {firstName, lastName} = instructor;
firstName; // "Elie"
lastName; // "Schoppik"
var instructor = {
firstName: "Elie",
lastName: "Schoppik"
}
var {firstName:first, lastName:last} = instructor;
first; // "Elie"
last; // "Schoppik"
function createInstructor(options){
var options = options || {};
var name = options.name || {first: "Matt", last:"Lane"}
var isHilarious = options.isHilarious || false;
return [name.first, name.last, isHilarious];
}
Lots of work!
createInstructor(); // ["Matt", "Lane", false]
createInstructor({isHilarious:true}); // ["Matt", "Lane", true]
createInstructor({name: {first:"Tim", last:"Garcia"}}); // ["Tim", "Garcia", false]
function createInstructor({name = {first:"Matt", last:"Lane"}, isHilarious=false } = {}){
return [name.first, name.last, isHilarious];
}
createInstructor(); // ["Matt", "Lane", false]
createInstructor({isHilarious:true}); // ["Matt", "Lane", true]
createInstructor({name: {first:"Tim", last:"Garcia"}}); // ["Tim", "Garcia", false]
var instructor = {
name: "Elie",
favColor: "Purple"
};
displayInfo(instructor); // ["Elie", "Purple"]
function displayInfo(obj) {
return [obj.name, obj.favColor];
}
function displayInfo({name,favColor}) {
return [name, favColor];
}
Very common in React!
var instructor = {
name: "Elie",
favColor: "Purple"
};
displayInfo(instructor); // ["Elie", "Purple"]
var arr = [1,2,3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
a; // 1
b; // 2
c; // 3
var arr = [1,2,3];
var [a,b,c] = arr;
a; // 1
b; // 2
c; // 3
function returnNumbers(a,b) {
return [a,b];
}
[first, second] = returnNumbers(5,10);
first; // 5
second; // 10
function returnNumbers(a,b) {
return [a,b];
}
var first = returnNumbers(5,10)[0];
var second = returnNumbers(5,10)[1];
first; // 5
second; // 10
//ES5
function swap(a,b){
var temp = a;
a = b;
b = temp;
return [a,b];
}
swap(10,5); // [5,10]
// ES2015
function swap(a,b){
return [a,b] = [b,a];
}
swap(10,5); // [5,10]