Skip to content

Instantly share code, notes, and snippets.

@zcaceres
Created March 24, 2017 22:01
Show Gist options
  • Save zcaceres/0180d81985dcea219a549197770c1b2f to your computer and use it in GitHub Desktop.
Save zcaceres/0180d81985dcea219a549197770c1b2f to your computer and use it in GitHub Desktop.
ES6 lecture. FSA 1702 – March 27, 2017

ES6

FSA 1702 – March 27, 2017


History

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 (let and const)

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.

Function Improvements (arrow and default args)

Sometimes called 'fat arrows'.

  • Much more concise
  • Implicit returns
  • Does not rebind the value of this
  1. Remove parens if there's only one parameter.
  2. 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 Improvements (templating)

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.

Object Improvements (destructuring)

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.

Modules

Whoops. We skipped this.

// my file
export

//other file
import

Classes

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
  }
}

Spread and Rest

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment