Skip to content

Latest commit

 

History

History
656 lines (460 loc) · 12.3 KB

ES6-Guide.md

File metadata and controls

656 lines (460 loc) · 12.3 KB

Introducing ES2015

ES6-1: ES2015 Basics

6th Edition to ECMA Script

ES6-2: Getting Started with ES2015

  • biggest change up to JS since its inception
  • JS built in 10 days
  • Microsoft used Jscript
  • ECMAScript and JavaScript are the same (ECMA named 1997)
  • ECMAScript 5 (2009)
  • Most browsers are using the latest
  • Babel can be used to compile for those using older browsers

Let and Const

  • so far, we need to be on top of scope
'use strict';

var hello = 'hello'

// ecma2015

A block can be either a loop, if statement or function

'use strict'

(function initLoop() {
	function doLoop(x) {
		console.log('loop: ', x);
	}

	for (var i=0; i < 10; i++) {
		doLoop(i + 1);
	}
})

...what can go wrong? Dirty Read

'use strict'

(function initLoop() {
	function doLoop(x) {
		i=3;
		console.log('loop: ', x);
	}

	for (var i=0; i < 10; i++) {
		doLoop(i + 1);
	}
})

We can fix this with the let keyword

'use strict'

(function initLoop() {
	function doLoop(x) {
		// i=3; -> this won't be allowed
		console.log('loop: ', x);
	}

	for (let i=0; i < 10; i++) {
		doLoop(i + 1);
	}
})

this will throw an error at us!

ES6-3: Duplicate values

'use strict';

var student = { name: 'Ken' };
var student = { name: 'James' };

console.log(student);

// student become James

'use strict';

const student = { name: 'Ken' };
var student = { name: 'James' };

console.log(student);

// we will now get an exception (happens for let or const)

- you can have different const variables of the same name for different constants

**not allowed**

... {
	const student = 'test';
	... {
		student = 'test'
	}
}

**allowed**

... {
	let student = 'test';
	... {
		student = 'test'
	}
}

** Use let when you need to reassign, use const when you do not want the value to change. **

ES6-4: Template Strings

** ES5 Strings **

let str = 'My favourite name is';

console.log(str, 5);

** ES2015 Strings **

// interpolation

const student = { name: 'James', followerCount: 34 }

${student.name}

<this stuff is neatly formatted>

ES6-5: String search methods

new functions:

startsWith endsWith includes

console.log(strToSearch.startsWith('example-at-start')); console.log(strToSearch.endsWith('example-at-end')); console.log(strToSearch.includes('example-in-the-middle'));

** all take an optional parameter **

startsWith('example', 5); //start search from 5th index endsWith('example', 21); //searches the first 21 characters


ES6-6: The Cooler Parts of ES2015

ES6-7: Arrow Functions

  • Bound to its parent scope

New syntax for writing functions

  • referred to as Lamda functions in other languages

** ES5 **

'use strict';

var Person = function (data) {
  for (var key in data) {
    this[key] = data[key];  
  }
  this.getKeys = function () {
    return Object.keys(this);
  }
}

var Alena = new Person({ name: 'Alena', role: 'Teacher' });

console.log('Alena\'s Keys:', Alena.getKeys()); // 'this' refers to 'Alena'

var getKeys = Alena.getKeys;

console.log(getKeys()); // 'this' refers to the node process

// throws error get getKeys()

ES2015

'use strict';

var Person = function (data) {
  for (var key in data) {
    this[key] = data[key];  
  }
  this.getKeys = () => {
    return Object.keys(this);
  }
}

var Alena = new Person({ name: 'Alena', role: 'Teacher' });

console.log('Alena\'s Keys:', Alena.getKeys()); // 'this' refers to 'Alena'

var getKeys = Alena.getKeys;

console.log(getKeys()); // 'this' refers to the node process

// this fixes it!

The lamda function binds the function to the instance of the person no matter where it was called

** Promises **

'use strict';

var Teacher = function (data) {
  this.name = data.name;
  this.greet = function (studentCnt) {
    let promise = new Promise(function (resolve, reject) {
      if (studentCnt === 0) {
        reject('Zero students in class');
      } else {
        resolve(`Hello to ${studentCnt} of my favorite students!`);
      }
    });
    return promise;
  }
}

var Classroom = function (data) {
  this.subject = data.name;
  this.teacher = data.teacher;
  this.students = [];
  this.addStudent = function (data) {
    this.students.push(data);
    this.greet();
  }
  this.greet = () => {
    this.teacher.greet(this.students.length).then(
      (function (classroom) {
        return function (greeting) {
          console.log(`${classroom.teacher.name} says: `, greeting);
        }
      })(this),
      function (err) {
        console.log(err);
      })
  }
}

var myTeacher = new Teacher({ name: 'James' });
var myClassroom = new Classroom({ name: 'The Future of JavaScript', teacher: myTeacher });

myClassroom.addStudent({ name: 'Dave' });

ES 2015 Promises

'use strict';

var Teacher = function (data) {
  this.name = data.name;
  this.greet = function (studentCnt) {
    let promise = new Promise(function (resolve, reject) {
      if (studentCnt === 0) {
        reject('Zero students in class');
      } else {
        resolve(`Hello to ${studentCnt} of my favorite students!`);
      }
    });
    return promise;
  }
}

var Classroom = function (data) {
  this.subject = data.name;
  this.teacher = data.teacher;
  this.students = [];
  this.addStudent = function (data) {
    this.students.push(data);
    this.greet();
  }
  this.greet = () => {
    this.teacher.greet(this.students.length).then(
      greeting => console.log(`${this.classroom.teacher.name} says: `, greeting);
	  error => console.log(err);
  }
}

var myTeacher = new Teacher({ name: 'James' });
var myClassroom = new Classroom({ name: 'The Future of JavaScript', teacher: myTeacher });

myClassroom.addStudent({ name: 'Dave' });

ES6-8: Default Parameters

Set default parameters for a function -> similar to other languages

ES5

'use strict'

function greet(name, timeOfDay) {
	name = name || 'Guil';
	timeofDay = timeOfDay || 'Day';
	...
}

greet();

**ES 2015**

'use strict'

function greet(name = 'Guil', timeOfDay = 'Day') {
	...
}

greet(undefined, 'Afternoon');	// defaults are optional, need to undefine

ES6-9: Rest Parameters and Spread Operator

How to use the rest parameters

  • rest must be the last parameter
function myFunction(name, ...params) {
	console.log(name, params);
}

myFunction('Andrew', 1, 2, 3);

// output Andrew [1, 2, 3]

Spread parameters

const originalFlavors = ['Chocolate', 'Vanilla'];

const newFlavors = ['Strawberry', 'Mint Chocolate Chip'];

const inventory = ['Rocky Road', ...originalFlavors, 'Neopolitan', ...newFlavors];

console.log(inventory);

// spitting an array and them using them as arguments using the spread operator

function myFunction(name, iceCreamFlavor) {
	console.log('${name} really likes ${iceCreamFlavor} ice cream.')
}

let args = ['Gabe', 'Vanilla'];

myFunction(...args);	// sends as separate arguments

ES6-10: Destructuring

Relatively simple concept

Let's you extract values from arrays or objects

let toybox = { item1: 'car', item2: 'ball', item3: 'frisbee' };

let { item3: disc} = toybox;

console.log(disc);

// logs item3 value

let widgets = ['wid1','wid2','wid3','wid4','wid5'];

let [a,b,c, ...d] = widgets;

ES6-11: Objects and New Collection Types

ES6-12: Object Property Shorthand

function submit(name, comments, rating = 5) {
	let data = { name, comments, rating };

	for (let key in data) {
		console.log(key + ':', data[key]);
	}

	// ... do ajax request
}

submit('English', 'Great course!');

// without a default name, the key because the parameter for the object
// works with all forms

ES6-13: for...of

For iterating over a data set

// previous for (let ... )
// ES5 gave us for each

let myNumbers = [1,2,3,4,5,6];

for (let number of myNumbers) {
	...
	if (example) {
		break; // you can break!
	}
}

// still use for...in for iterating over regular objects

ES6-14: Set

let classroom = new Set(); // unique collection of values

let stevenJ = { name: 'Steven', age: 22 },
	sarah = { name: 'Sarah', age: 23 },
	stevenS = { name: 'Steve', age: 22 }

classroom.add(stevenJ);
classroom.add(sarah);
classroom.add(stevenS);

if (classroom.has(stevenJ)) console.log('stevenJ is in the classroom');	//true
if (classroom.has(sarah)) console.log('sarah is in the classroom');	//true
if (classroom.has(stevenS)) console.log('sarah is in the classroom'); //true

BUT IF stevenS = stevenJ

let stevenJ = { name: 'Steven', age: 22 },
	sarah = { name: 'Sarah', age: 23 },
	stevenS = stevenJ;

classroom.add(stevenJ);
classroom.add(sarah);
classroom.add(stevenS);

if (classroom.has(stevenJ)) console.log('stevenJ is in the classroom');	//true
if (classroom.has(sarah)) console.log('sarah is in the classroom');	//true
if (classroom.has(stevenS)) console.log('sarah is in the classroom'); //true

console.log(classroom.size()); //3

classroom.delete(stevenJ)

console.log(classroom.size()); //2

// Create array of students from the classroom set

let arrayOfStrudents = Array.from(classroom);
console.log(arrayOfStudents);

// Create set from set

let alumni = new Set(arrayOfStudents);

ES6-15: Map

'use strict'

let classroom = new Map();

let stevenJ = { name: 'Steven', age: 22 },
    sarah = { name: 'Sarah', age: 23 },
    stevenS = { name: 'Steven', age: 22 };

classroom.set('stevenJ', stevenJ);
classroom.set('sarah',sarah);
classroom.set('stevenS', stevenS);

console.log(classroom.size);

if (classroom.has('stevenJ')) console.log('stevenJ is in the classroom');
if (classroom.has('sarah')) console.log('sarah is in the classroom');
if (classroom.has('stevenS')) console.log('stevenS is in the classroom');

console.log('sarah:', classroom.get('sarah'));

classroom.delete('sarah');
classroom.clear();        //deletes all

for (let student of classroom) {
  console.log('${student[0]} : ${student[1].name} is ${student[1].age} years old');
}

ES6-16: Classes

ES6-17: Structure of a Class

A class is a blueprint for those that share similar properties or methods

// old way

let Student = function(data) {
  this.name = data.name;
  this.age = data.age
}

// new way

class Student {
  constructor({ name, age, interestLevel = 5 } = {}) {
    this.name = name;
    this.age = age;
    this.interestLevel = interestLevel;
    this.grades = new Map();
  }
}

let sarah = new Student('Sarah', 11);

console.log(Array.from(sarah.grades));

ES6-18: Subclasses

  • classes can inherit from other classes
  • var hoisting
  • destructuring is one way to set default values for class properties
bla = 2
var bla;
// ...

// is implicitly understood as:

var bla;
bla = 2;
class Person {
  dance() {
    const dances = [
      'waltz',
      'tango',
      'mambo'
    ];

    console.log(${this.name} is doing the ${dances[Math.floor(Math.random()*dances.length)]}!);
  }
  constructor({ name, age, eyeColor = 'brown' } = {}) {
    this.name = name;
    this.age = age;
    this.eyeColor = eyeColor;
  }
}

class Student extends Person {

  dance(traditional) {
    if (traditional) {
      super.dance();
      return;
    }

    const dances = [
      'lyrical',
      'tap',
      'jazz'
    ];

    console.log(${this.name} is doing the ${dances[Math.floor(Math.random()*dances.length)]}!);
  }

  constructor({ name, age, interestLevel = 5 } = {} ) {
    super({ name, age });
    this.name = name;
    this.age = age;
    this.interestLevel = interestLevel;
    this.grades = new Map;
  }
}

let stevenJ = new Student({name: 'Steven', age: 22, interestLevel: 3 });
stevenJ.dance();

ES6-19: Static Methods

class Bird {
  static changeColor(color) {
    this.color = color;
  }
  constructor({ color = 'red' } = {}) {
    this.color = color;
  }
}

let redBird = new Bird;
console.log(redBird.color);
redBird.changeColor('blue');
console.log(redBird.color); // would call an error!

// what we could do

Bird.changeColor.call(redBird, 'blue');
console.log(redBird.color);

/* the other option is to change the changeColor function to accept (bird, color) and then change this.color to bird.color
*/

ES6-20: Getter and Setter methods in a class

class Bird {
  changeColor(color) {
    this.color = color;
  }

  set color(color) {
    this.color = color;
  }

  get color() {
    return this.color;
  }

  constructor({ color = 'red' } = {}) {
    this.color = color;
  }
}