ES6 workshop
Contents
- let and const
- Template literals
- Enhanced object literals
- Object destructuring
- Rest operator
- Spread syntax
- Arrow functions
- Symbols
- Set and Map
- Iterators
- Generators
- Proxies
Short history
-
1995
- May - Mocha invented by Brendan Eich at Netscape (in 10 days!)
- September - renamed to LiveScript
- December - renamed to JavaScript (because JAVA...)
- 1996 - ECMA takes JavaScript to standardization
- 1997 - ECMA-262 (ECMAScript)
- 1998 - ECMAScript 2
- 1999 - ECMAScript 3
- 2005 - Mozilla and Macromedia began to work on ECMAScript 4 - never released => ECMAScript 3.1
- 2009 - ES5 emerges from previous discussions
-
2015 - ES6 standard
- Version names based on year of release (ES2015, ES2016
let and const
var is function scoped, cons and let are block (lexical) scoped
- var declarations are hoisted to the top of the function
- let declarations hoisted to the top of the block but cannot be used before initialization (temporal dead zone)
- const declarations must be initialized
- let and const cannot be redeclared
- let allows for reassignment, const does not (not the same as immutable - for immutability we can use Object.freeze and/or Object.seal)
Template literals
- string literals that allow embedded expressions
- back-ticks (`) are used to enclose the string
- anything inside ${} is evaluated
- new lines are retained
- tag templates - customize the resulting output string - useful for l10n/i18n or html sanitising
Enhanced object literals
-
property initializer shorthand
-
concise method names
-
computed property names
-
new Object methods
-
Object.is() - make up for the remaining quirks of the identically equals operator
-
Object.assign(receiver, suppliers) - copy properties from supplier into receiver
-
Object.getOwnPropertyNames() - return all properties of an object (as opposed to only enumerable for Object.keys())
-
Object destructuring
-
de-structure a target objects' properties
-
works on all objects (including arrays)
-
can have default values for undefined properties
-
default values evaluation is similar to a list of let variables declaration
Rest operator
-
rest parameters for functions and rest items for arrays
-
use the ... operator to:
-
represent an indefinite number of function parameters as an array
-
to assign remaining values in an array to a particular value
-
Spread syntax
allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables (for destructuring assignment) are expected
a replacement for apply
easier array operations
easier copy operation for arrays and objects
Arrow functions
-
shorthand for the function expression
-
does not bind its own this, arguments, super or new.target
-
preserves the 'this' of the calling location
-
best suited for non-method functions
-
are always anonymous
-
cannot be used as constructors and do not have a prototype
-
does not bind to an arguments object -> use rest params
Recap
function() {
if(true) {
var x = 1;
}
console.log(x) // 1
}
Block level scoping: const and let
function() {
for(var i=0;i< 10;i++) {
var x = 1;
}
console.log(i) // 10
console.log(x) // 1
}
function() {
if(true) {
let x = 1;
}
console.log(x) // x doesn't exist here
}
function() {
let x = 1;
if(true) {
let x = 2; // error cannot reasign
}
}
function() {
const a; // error, need to initialize const
const b = 1;
b = 2; // error cannot reasign
}
function() {
for(var i=0; i<10; i++) {
let x = 1;
}
console.log(i, x) // i, x don't exist here
}
Recap
var firstName = "Andrei",
lastName = "Antal";
var fullName = "The full name is: " + firstName + " " + lastName
Template strings
var fullName = `The full name is: ${firstName} ${lastName}`;
function() {
return (new Date()).year;
}
var currentYear = `The cuurent Year is ${getYear()}`;
var theSum = `The sum is ${3 + 4 / 2}`;
const theString = upp`Hello ${firstName} ${lastName}!`;
function upp(literal, name, name2) {
return [
literal[0],
name,
literal[1],
name2.toUpperCase(),
literal[2],
].join("");
}
Recap
const name = "Andrei";
const age = 29;
const user1 = {
name: name,
age: age,
sayHello: function() {
console.log("Yo!");
}
}
Enhanced object literals
const user2 = {
name,
age,
sayHello() {
console.log("Yo!");
}
}
const firstName = "first name";
const suffix = " name";
const person = {
[firstName]: "Andrei",
["last" + suffix]: "Antal"
};
const obj1 = {
a: 'a',
b: 'b',
};
const obj2 = { b: 'c' };
Object.assign(obj1, obj2); // obj1 = { a: 'a', b: 'c' }
Object.assign({}, obj1, obj2); // { a: 'a', b: 'c' }
Recap
let options = {
repeat: true,
save: false
};
let repeat = options.repeat;
let save = options.save;
Destructuring
let {repeat, save} = options;
console.log(repeat); // true
console.log(save); // false
let {repeat: re, save: sa, stop: st = false} = options;
console.log(re, sa, st); // true, false, false
let [one, two, three] = [1,2,3];
console.log(one, two, three); // 1,2,3
let [, , three] = [1,2,3];
console.log(three); // 3
Recap
const animal = {
name: 'Dog',
sound: 'wof'
};
function makeSound(options) {
options.name = options.name || 'animal';
console.log(`The ${options.animal} goes ${options.sound}`)
}
Destructuring
function makeSound({name = 'animal', sound}) {
console.log(`The ${name} goes ${sound}`)
}
makeSound(animal);
Recap
function doSomething(a,b, ...rest) {
console.log(a);
console.log(b);
console.log(rest);
}
doSomething(1,2,3,4,5); // 1, 2, [3,4,5]
function doSomething(a,b, ...rest, c){} // error; rest must be the last in param list
Rest operator
const arr = [1, 2, 3, 4, 5];
const [,, ...arr1] = arr;
console.log(arr1); // [3, 4, 5]
function doSomething(a,b, ...[c,d,e]){
console.log(a);
console.log(b);
console.log(c,d,e);
}
doSomething(1,2,3,4,5);
Recap
function logNumbers(a, b, c) {
console.log(a)
console.log(b)
console.log(c)
}
const array = [1,2,3];
logNumbers(...array);
Spread
const array = [1,2,3];
console.log([...array, 4, 5]);
const obj1 = {a: 'a', b: 'b'};
const obj2 = {c: 'c', ...obj1};
console.log(obj2);
const arr1 = [1,2,3];
const arr2 = [2,3,4];
const arr3 = [...arr1, 8, ...arr2];
console.log(arr3);
Recap
const sum = (num1, num2) => { return num1 + num2 };
const sum = function(num1, num2) {
return num1 + num2;
};
Arrow functions
const square = value => value * value;
const square = function(value) {
return value * value;
};
const getName = () => "Andrei";
const getName = function() {
return "Andrei";
};
const getTempItem = (id) => ({ id: id, name: "Temp" });
const getTempItem = function(id) {
return {
id: id,
name: "Temp"
};
};
Recap
const sum = (num1, num2) => { return num1 + num2 };
const sum = function(num1, num2) {
return num1 + num2;
};
Arrow functions
const square = value => value * value;
const square = function(value) {
return value * value;
};
const getName = () => "Andrei";
const getName = function() {
return "Andrei";
};
const getTempItem = (id) => ({ id: id, name: "Temp" });
const getTempItem = function(id) {
return {
id: id,
name: "Temp"
};
};
Classes
-
syntactic sugar over over JavaScript's existing prototype-based inheritance - does not create a new object oriented inheritance model
-
classes are defined using the class keyword
-
class declarations are not hoisted
- a class contains
- constructor - class initialization
- methods (we can also create also static methods)
- properties (only using getters)
- we can create hierarchies using the extends keyword
- we ca use super() to call an object's parent
Symbols
-
a primitive (value) data type whose instances are unique and immutable
-
for debugging purposes symbols can have an optional description - stored in the [[Description]] property
-
symbols do not have a literal form, so they do not coerce into other primitive types
-
mostly used to create private properties - symbol keys are not visible in iterations
-
ES6 provides a global symbol registry in order to share symbols across the app
Set and Map
-
extra data types for working with collections (besides the Array data type)
-
can store primitive or object values
-
Set - iterable list of objects that cannot contain duplicates; elements are set in the insertion order
-
Map - iterable key/value pair entries list - keys can be objects, symbols, primitives and functions
-
WeakMap, WeakSet - non enumerable versions where keys/entries are referenced weakly - can be garbage collected if they aren't referenced elswhere
Iterators
- iterators - objects with special interfaces designed for iteration
- affects behaviour in for...of loops and the ... operator
- the iterable protocol - customize iteration behaviour
- implement @@iterator method (or [Symbol.iterator]) that returns an iterator
- the iterator protocol - implement a next() method that returns an object with 2 keys:
- value - current value in iteration
- done - boolean (true when there are no more items in the enumeration)
Generators
-
generator - object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.
-
declared by adding a "*" between function and the name
-
use the yield keyword to denote execution halt until the next() method is called
-
each yield return an iteration (value, done) object
Proxies
-
proxy objects are used to define custom behavior for fundamental operations
-
create a proxy to use in place of another object (called the target)
-
intercept low-level object operations on the target (using a trap) that are otherwise internal to the JavaScript engine
-
use the Proxy constructor to make a proxy - pass it two arguments: the target and a handler (an object that defines one or more traps)
Other ES stuff
-
module system
-
native promises
-
tail call optimization
ES6 workshop
By Andrei Antal
ES6 workshop
- 1,232