- Last class we covered several of the new features in es2015
- Tonight we'll continue exploring:
- Rest and Spread
- Destructuring
- Class Syntax (NO! classes still do not exist in JS)
- ES6 Modules
- Sets and Maps
The rest parameter lets you pass an indefinite number of arguments as an array.
Rest parameters are invoked using the ... syntax
This is similar to the arguments object that we learned about way back in class #3. However, rest paramaters offer significant advantages.
function add() {
console.log("arguments object:", arguments);
var numbers = Array.prototype.slice.call(arguments),
var sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
}
console.log(add(1,2,3,4,5,6,7,8));
// arguments object: {"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7,"7":8}
// 36In the above example, we had to convert the arguments object into an array, because it's not an actual array
Rest parameters on the other hand, provides an actual array
meaning methods like sort, map, forEach and pop can be applied on it directly.
let add = (...numbers) => {
console.log("rest parameters:", numbers);
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
}
console.log(add(1,2,3,4,5,6,7,8));
// rest parameters: [1,2,3,4,5,6,7,8]
// 36As you can see, this new syntax is much more readable.
You can immediately tell this function can take any number of arguments.
Just for fun, lets use reduce to make our add function a one-line statement
let add = (...numbers) => numbers.reduce((sum, number) => sum += number, 0)
console.log(add(1,2,3,4,5,6,7,8));
// 36It's also possible to combine rest parameters with multiple arguments
function addStuff(x, y, ...z) {
return (x + y) * z.length
}
console.log(addStuff(1, 2, "hello", "world", true, 99));
// 12note: rest paramaters must be your last argument in the function signature
The spread operator allows us to split and Array argument into individual elements.
let random = ["Hello", "world", true, 99];
let newArray = [1,2, ...random, 3];
console.log(newArray);
//[1,2,"Hello","world",true,99,3]Another example, spreading out the characters in the hi variable
let hi = "Hello World"
let hiArray = [ ...hi ]
console.log(hiArray);
// ["H","e","l","l","o"," ","W","o","r","l","d"]Though the syntax is virtually the same, rest and spread serve different purposes...
- rest
- gathers values and stores them in an array
- is used in function signatures (as an argument)
- spread
- spreads the values into individual array items
- used in the function body
let restExample = (...z) => {
console.log(z)
return z
}
restExample("hello", "world")
//["hello", "world"]let spreadExample = (item) => {
let spreadArray = [...item]
console.log(spreadArray);
return spreadArray
}
spreadExample("Hello World");
// ["h","e","l","l","o"," ","w","o","r","l","d"]- complete exercises (18)[http://tddbin.com/?229#?kata=es6/language/rest/as-parameter] - 21 (skipping #19) on Rest and Spread operators at ES6Katas
With destructuring you can store array items as individual variables during assignment.
Consider the following examples:
var students = ["Julian", "AJ", "Matt"];
var x = students[0];
var y = students[1];
var z = students[2];
console.log(x, y, z);
// Julian AJ Mattlet students = ["Julian", "AJ", "Matt"];
let[x,y,z] = students
console.log(x,y,z);
// Julian AJ MattAs you can see, this incredibly useful and readable. It also allows for scalability of your code.
Destructuring also allows you to omit values
let students = ["Julian", "AJ", "Matt"];
let[ ,y,z] = students
console.log(y,z);
// AJ Mattlet students = ["Julian", "AJ", "Matt"];
let[x,,y] = students
console.log(x,y);
// Julian MattNow that you know how to use destructuring with and rest parameters, how would you implement both concepts
let students = ["Julian", "AJ", "Matt"];
let[x, ...rest] = students;
console.log(x, rest);
// Julian ["AJ","Matt"]How would this work with functions?
let completedHomework = () => {
return ["Julian", "AJ", "Matt"];
}
let [x,y,z] = completedHomework();
console.log(x,y,z);Destructuring also works with objects
let instructor = {
name: "Shane",
email: "shane@techtalentsouth.com"
}
let { name: x , email: y } = instructor;
console.log(x);
// ShaneLet's use destructuring and default parameters in a function:
let instructor = {
name: "Shane",
}
function teacher({name, email = "info@techtalentsouth.com"}) {
console.log(name, email)
}
teacher(instructor);
// Shane info@techtalentsouth.com- complete challenges 10-15 (Destructuring) at ES6Katas
One of the most interesting/exciting features of ES2015 is the introduction of Object Oriented Keywords. The benefit of this feature, is that developers more accustomed to Object Oriented Programming can more easily work with Constructors and Prototypes.
note: the class features simply syntactic sugar, not an actual change to the functional nature of JavaScript
function Person (name, job) {
this.name = name;
this.job = job;
};
Person.prototype.getName = function getName () {
return this.name;
};
Person.prototype.getJob = function getJob () {
return this.job;
};
var goodGuy = new Person('Jim Gordon', 'Commissioner');
console.log(goodGuy.getName());
// Jim Gordonclass Person {
constructor (name, job) {
this.name = name;
this.job = job;
}
getName () {
return this.name;
}
getJob () {
return this.job;
}
}
let goodGuy = new Person('Jim Gordon', 'Commissioner');
console.log(goodGuy);
//Jim GordonFor those of you that have experience in Ruby or Python, this syntax should look and feel familiar.
- Use the
classkeyword followed by a capitalized name - add a constructor function
- add instance methods that give you access to the object's properties
This syntatic sugar also provides a really nice and clean way to create inheritance chains
note remember that JS inhertance is still instance based (not class based)
function Person (name, job) {
this.name = name;
this.job = job;
};
Person.prototype.getName = function getName () {
return this.name;
};
Person.prototype.getJob = function getJob () {
return this.job;
};
function SuperHero (name, heroName) {
Person.call(this, name, heroName);
}
SuperHero.prototype = Object.create(Person.prototype);
SuperHero.prototype.constructor = SuperHero;
SuperHero.parent = Person.prototype;
SuperHero.prototype.getJob = function () {
return 'I am '+ this.job + "!"
};
var batman = new SuperHero('Bruce Wayne', 'Batman');
console.log(batman.getJob()); As you can see, this is pretty verbose. Let's take a look at the ES2015 way
class Person {
constructor (name, job) {
this.name = name;
this.job = job;
}
getName () {
return this.name;
}
getJob () {
return this.job;
}
}
class SuperHero extends Person {
constructor (name, heroName, superPower) {
super(name);
this.heroName = heroName;
this.superPower = superPower;
}
secretIdentity(){
return `${this.heroName} is ${this.name}!!!`
}
}
let batman = new SuperHero("Bruce Wayne", "Batman");
console.log(batman.secretIdentity())
// Batman is Bruce Wayne!!!The 3 things that you'll notice:
- create a new SuperHero
class - use the
extendskeyword to indicate you want to inherit from the Personclass
after all, superhero's are People too - the use of
super()allows us to:- reuse the exisiting
namefunctionality from the Personclass - add superhero specific features to our constructor function
- reuse the exisiting
If you have experience with Object Oriented programming, chances are you're familiar with getters and setters
Getters allow us to easily read (access) an object's property.
Setters allow us to write (modify) an object's property.
class Person {
constructor (name) {
this.name = name;
}
set name (name) {
this._name = name;
}
get name () {
return this._name
}
}
let goodGuy = new Person('Jim Gordon');
console.log(goodGuy.name);
// Jim Gordon
goodGuy.name = "James Gordon";
console.log(goodGuy.name);
// James Gordon- ES2015 gives us a new way to easily add existing variables to objects.
let name = "Shane";
let job = "Developer";
let instructor = { name, job };
console.log(instructor);
// {"name":"Shane","job":"Developer"}Complete Exercises #22-28 at ES6 Katas
As you know, we've already talked about Modules quite a bit.
ES2015 offers a module syntax that encapsulates our code.
This provides several significant benefits including:
- avoids naming conflicts
- removes global variables
- better control over scope
- better control over 3rd party libraries
- logical load order
- faster tests
To many, this is the most exciting feature of ES2015
Modules consist of export and import statements
According to Mozilla:
Export:
...is used to export functions, objects or primitives from a given file (or module).
Import:
...is used to import functions, objects or primitives that have been exported from an external module, another script, etc.
let's take a look some basic examples:
// ./src/calculator.js
export function add(...numbers) {
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
}// .src/index.js
import {add} from './calculator';
console.log(add(1,2,3));// ./src/calculator.js
export function add(...numbers) {
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
};
export function subtract(x,y) {
return x - y;
};// .src/index.js
import {add, subtract} from './calculator';
console.log(add(1,2,3));
console.log(subtract(6,2));Variables and Constants can also be exported
// ./src/calculator.js
export const numbersArray = [1,2,3,4,5];// ./src/index.js
import _ from 'lodash';
console.log(_.shuffle(numbersArray));Default Exporting allows you to set one item as default. This is helpful with a module or class that returns a single value
// ./src/calculator.js
export default function add(...numbers) {
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
};// ./src/index.js
import add from './calculator';
console.log(add(1,2,3));Only one default can be clarified per module.
Modules can, however, have default and named exports
// ./src/calculator.js
export default function add(...numbers) {
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
};
export function subtract(x,y) {
return x - y;
};// ./src/index.js
import add, {subtract} from './calculator';
console.log(add(1,2,3));
console.log(subtract(6,2));One final way to import is by using the * (all, wildcard) operator. This syntax will import all exports.
// ./src/calculator.js
export function add(...numbers) {
let sum = 0;
numbers.forEach(function (number) {
sum += number;
});
return sum;
};
export function subtract(x,y) {
return x - y;
};// ./src/index.js
import * as calculate from './calculator';
console.log(calculate.add(1,2,3));
console.log(calculate.subtract(6,2));As you can see, writing modular code is the future of JavaScript. The modular pattern will be heavily used as we move into building applications with React.
Complete Exercise #61 at ES6 Katas
Map is a new way to store key/value pairs, while similar to objects Map is a bit more reliable when storing key/values. This is due to the fact that Objects convert both keys and values to strings.
According to Mozilla
The Map object is a simple key/value map. Any value (both objects and primitive values) may be used as either a key or a value.
let student = {name: "Latori"};
let status = new Map();
status.set(name, "Latori");
status.set("feeling", "awesome")
console.log(status.get(name));
console.log(status.get("feeling"))
//Latori
//awesome- to set a value use
set - to get an object use
get
Set is a collection of unique values
let student = new Set();
student.add('Katy').add({mood: "happy"});
console.log(student);
// ["Katy",{"mood":"happy"}]WeakMap works like Map, with a few small differences.
- The keys must be objects
- Allows for garbage collection of keys
- does not allow iteration
let weakMap = new WeakMap();
let student = {}
weakMap.set(student,"Lee");
console.log(weakMap.get(student));
// LeeWeakSet
Like WeakMap for Sets
let weakSet = new WeakSet();
let student = {
name: "Heather"
};
weakSet.add(student);
console.log(student);
// {"name":"Heather"}###Due 9/6/16
- complete the remainder of the Count to 6 NodeSchool Module
- complete the tower-of-babel NodeSchool Module
- upload screenshots to slack
- complete challenges 10-15, 22-28, and 61 at ES6 Katas
- upload completed screenshots to slack
###Due 9/8/16
- complete this ES2015 tutorial
- push the code to our class GitHub using the naming convention
es6_tutorial_YOUR_INITIALS_HERE
- push the code to our class GitHub using the naming convention
- watch these 2 videos:

