FSA 1702 – March 27, 2017
ECMA Script 6 (ES2015). A weird name that arose from a copyright dispute (European Computer Manufacturing Association).
Standardizing and updating the language is meant to make the lives of developers easier and simpler. Never perfectly aligned across browsers, but does get better over time. ES6 still has some unsupported functionality.
Variable Improvements:
- var - function scoped
- let – block scoped
- const – block scoped
function setAge() {
var age = 1234
console.log(age);
}
console.log(age); // undefined!
// 1. let is BLOCK SCOPED
var age = 55;
if (age > 40) {
let favHobby = 'golf';
console.log('i love', favHobby)
}
// favHobby not defined outside the scope here -- because it is within the curly braces (if statement block)
// 2. var can be redeclared, let and const cannot!
var name = 'Harry';
var name = 'Hermione';
// this is fine
let name = 'Harry';
let name = 'Hermione';
// error: "Identifier 'name' has already been declared"
/* 3. const are for constants
const has to point to the same thing. We can change the thing that it points to. But we can't change where it points.
*/
var favFood = 'tacos';
favFood = 'pizza';
// We aren't changing the string itself (they are immutable), we are changing where favFood points.
const homeTown = 'chichester'
hometown = 'portsmouth'
// error "Assignment to constant variable";
const myObject = {age: 3, legs: 2}
myObject.age++
console.log(myObject.age) // will be 4!
// We changed the property inside the object where the const points but we cannot point it somewhere else.
const myArr = ['lamp']
myArr.push('stuff'); // This works ok, because we are just changing the mutable content of myArr not where it points.
Change everything to const
. Then if it complains, start using let
.
for(var i = 0; i< 5; i++) {
setTimeout(function() {
console.log(i)
}, 1000*i);
}
// This will log 5 over and over! We need a closure or a bind expression to fix this.
for(let i = 0; i< 5; i++) {
setTimeout(function() {
console.log(i)
}, 1000*i);
}
// Or `let` fixes this. Awesome. NO MORE CLOSURE!
const
and let
are not hoisted.
Sometimes called 'fat arrows'.
- Much more concise
- Implicit returns
- Does not rebind the value of
this
- Remove parens if there's only one parameter.
- If it's a one-liner, remove the curly braces and the
return
!
var add = function (a,b) {
return a + b
}
const add = (a,b) => {
return a + b
}
// more concise
var double = function (x) {
return x * 2
}
const double = (x) => {
return x*2
}
// only slightly more concise, does not use all ES6 arrow function possibilities
const double = x => x * 2
// Super concise!
const films = [
'movieOne',
'movieTwo',
'movieThree'
]
films.map(function(film) {
return `<li>${film}</li>`
});
// will create a list (li) of films
films.map(film => `<li>${film}</li>`)
// If the function is on one line, then you can remove return
films.map((film, i) => ({filmName: film, index:i}))
// Watch out! If you want to implicitly return an object you need to tell the function that those curlies are for the object and not for the function!
Arrow functions do not automatically rebind this
. They bind this
to the parent's scope.
Great for nested methods or promises so you don't need to worry about passing or rebinding this
, you can use the outer this
.
- instead of
self = this
- instead of
.bind(this)
Let's do:
button.addEventListener('click', function() {
setTimeout(() => console.log(this), 1000)
});
Will work. The keyword this
will refer to the button.
String interpolation allows you to put vars and Javascript directly into string. Functions, too.
const adjective = 'cool'
const noun = 'dog'
console.log('Here is my ${adjective} ${noun}')
// Here is my cool dog.
const age = 2;
console.log('Here is my ${adjective} ${noun} who is ${age + 3} years old');
// Here is my cool dog who is 5 years old.
const getAge = function() {
return 2 + 5;
};
console.log('Here is my ${adjective} ${noun} who is ${getAge()} years old');
// Here is my cool dog who is 7 years old.
Always use template strings rather than traditional string concatenation.
const lordOfDarkness = {
name: 'Lord',
house: 'A Dark Place'
}
const {name, house} = lordOfDarkness
console.log(name, house);
// You'll see name and house now.
// This is destructuring an object to make deeply nested values/keys available.
function makeWizard( name, age, house) {
return {name, age, house}
}
//Both of these set name and house keys of the object to the values of the vars with the same name
const {name: firstName, house} = lordOfDarkness
console.log(firstName, house);
// Still deconstructs the object, but allows us to reference it as firstName
const {atBirth, later} = lordOfDarkness.name.firstName;
// If we were getting nested properties, just get the nested value once.
Whoops. We skipped this.
// my file
export
//other file
import
Syntactic sugar to make it easier to write prototypal inheritance.
- Unlike other languages, Javascript does not have traditional class inheritance.
- Helps make JS easier for other developers and eliminates boilerplate.
- Does not add new functionality!
function Dog(name, breed) {
this.name = name;
this.breed = breed;
}
Dog.prototype.bark = function() {
console.log('arf');
}
//static (class) methods
Dog.fetchAll = function () {
// do stuff
}
// New Class Syntax
class Dog {
// constructor runs every time I run `new Dog('fluffy, pitbull')`
constructor (name, breed) {
this.name = name;
this.breed = breed;
}
// instance method
bark () {
console.log('arf!');
}
// Class method
static fetchAll() {
// do stuff
}
}
// INHERITANCE
// OLD WAY...
function Animal (name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log('my name is ' + this.name)
}
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
// NEW WAY
class Animal {
constructor (name) {
this.name = name
}
sayName () {
// do stuff
}
}
// inheritance
class Dog extends Animal {
constructor (name, breed) {
super(name);
this.breed = breed;
}
bark () {
// say arf
}
}
Rest takes a comma delineated grouping and turns it into an array
// Turn any comma delineated list into an array with `...`
function addNumbers(...nums) {
console.log(nums);
return nums.reduce((curr, prev) => curr + prev, 0));
}
// spread does the opposite with `...` before an array
...['string', 'otherString', 'final string', 'thing'];
// An array is like a tub of butter that I SPREAD
// Rest is the opposite