1995
ES3
1999
ES5
2009
ES6
2015
ES4
2007
1995
JavaScript is introduced by Brendan Eich as part of Netscape.
ES3
1999
ES5
2009
ES6
2015
ES4
2007
JavaScript is introduced by Brendan Eich as part of Netscape.
- try/catch
- RegExp
- String functions
- much of the core language used today
1995
ES3
1999
ES5
2009
ES6
2015
ES4
2007
JavaScript is introduced by Brendan Eich as part of Netscape.
- try/catch
- RegExp
- String functions
- much of the core language used today
- Types
- Classes
- Modules
- (other)
1995
ES3
1999
ES5
2009
ES6
2015
ES4
2007
JavaScript is introduced by Brendan Eich as part of Netscape.
- try/catch
- RegExp
- String functions
- much of the core language used today
- Types
- Classes
- Modules
- (other)
- getter/setters
- JSON parsing
- strict mode
1995
ES3
1999
ES5
2009
ES6
2015
ES4
2007
JavaScript is introduced by Brendan Eich as part of Netscape.
- try/catch
- RegExp
- String functions
- much of the core language used today
- Types
- Classes
- Modules
- (other)
- getter/setters
- JSON parsing
- strict mode
- Classes
- Modules
- Object APIs
- Collections- Rest/Spread
- (other)
1995
ES3
1999
ES5
2009
ES6
2015
ES4
2007
Goals for ES6 is to be a better language for writing:
var x = 10; // function or global scope (good old var)
let y = 10; // block scoped
const MY_NUMBER = 10; // can't change it, block scoped
function test() {
var x = 10;
if (true) {
let x = 15;
let y = 20;
console.log(x); // 15
console.log(y); // 20
}
console.log(x); // 10
console.log(y); // ReferenceError y is not defined
}
function test() {
var x = 10;
if (true) {
let x = 15;
let y = 20;
console.log(x); // 15
console.log(y); // 20
}
console.log(x); // 10
console.log(y); // ReferenceError y is not defined
}
if (true) {
console.log(value); // ReferenceError!
let value = "blue";
}
var funcs = [];
for(var i=0; i<5; i++){
funcs.push( function(){
console.log( i );
});
}
funcs[3](); // 5
var funcs = [];
for(let i=0; i<5; i++){
funcs.push( function(){
console.log( i );
});
}
funcs[3](); // 3
var funcs = [];
for(var i=0; i<5; i++){
funcs.push( function(){
console.log( i );
});
}
funcs[3](); // 5
var funcs = [];
for(let i=0; i<5; i++){
funcs.push( function(){
console.log( i );
});
}
funcs[3](); // 3
Tip: use let instead of var
{
var MAX_ITEMS = 2;
console.log( a ); // 2
a = 3; // This is valid!
}
The old way
{
var MAX_ITEMS = 2;
console.log( a ); // 2
a = 3; // This is valid!
}
The old way
The new way
{
const MAX_ITEMS = 2;
console.log( a ); // 2
a = 3; // TypeError!
}
function foo(x,y) {
x = x || 11;
y = y || 31;
console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17
foo( 0, 42 ); // 53 <-- Oops, not 42
The old way
function foo(x,y) {
x = x || 11;
y = y || 31;
console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17
foo( 0, 42 ); // 53 <-- Oops, not 42
The old way
The new way
function foo(x = 11, y = 31) {
console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17
foo( 0, 42 ); // 42
// only the first parameter is expected to be passed all the time
function makeRequest(url, timeout = 2000, callback = function() {}) {
...
}
// uses default timeout and callback
makeRequest("/foo");
// uses default callback
makeRequest("/foo", 500);
// doesn't use defaults
makeRequest("/foo", 500, function(body) {
doSomething(body);
});
function logMyBooks(){
Array.isArray(arguments); // false
var books = Array.prototype.slice.call(arguments);
books.forEach(function(book){
console.log(book);
})
}
logMyBooks('Book 1','Book 2');
The old way
function logMyBooks(){
Array.isArray(arguments); // false
var books = Array.prototype.slice.call(arguments);
books.forEach(function(book){
console.log(book);
})
}
logMyBooks('Book 1','Book 2');
The old way
The new way
function logMyBooks(...books){
Array.isArray(books); // true
books.forEach(function(book){
console.log(book);
})
}
logMyBooks('Book 1','Book 2');
function logMyBooks(){
Array.isArray(arguments); // false
var books = Array.prototype.slice.call(arguments);
books.forEach(function(book){
console.log(book);
})
}
logMyBooks('Book 1','Book 2');
The old way
The new way
function logMyBooks(...books){
Array.isArray(books); // true
books.forEach(function(book){
console.log(book);
})
}
logMyBooks('Book 1','Book 2');
function logMyBooks(author, ...books){
console.log(author, books); // 'Martin' [Book 1','Book 2']
}
logMyBooks('Martin','Book 1','Book 2');
function logMyBooks(book1, book2){
console.log(book1, book2);
}
logMyBooks.apply(null, ['Book 1','Book 2']);
let values = [25, 50, 75, 100]
console.log(Math.max.apply(Math, values)); // 100
The old way
function logMyBooks(book1, book2){
console.log(book1, book2);
}
logMyBooks.apply(null, ['Book 1','Book 2']);
let values = [25, 50, 75, 100]
console.log(Math.max.apply(Math, values)); // 100
The old way
The new way
function logMyBooks(book1, book2){
console.log(book1, book2);
}
logMyBooks(...['Book 1','Book 2']);
let values = [25, 50, 75, 100]
console.log(Math.max(...values)); // 100
function logMyBooks(book1, book2){
console.log(book1, book2);
}
logMyBooks.apply(null, ['Book 1','Book 2']);
let values = [25, 50, 75, 100]
console.log(Math.max.apply(Math, values)); // 100
The old way
The new way
function logMyBooks(book1, book2){
console.log(book1, book2);
}
logMyBooks(...['Book 1','Book 2']);
let values = [25, 50, 75, 100]
console.log(Math.max(...values)); // 100
Concatenate arrays
let a = [1, ...[2,3], 4]; // [1, 2, 3, 4]
let x = ['a', 'b'];
let y = ['c'];
let z = ['d', 'e'];
let xyz = [...x, ...y, ...z]; // ['a', 'b', 'c', 'd', 'e']
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let month = today().month, day = today().day;
console.log(month, day); // 6 2
The old way
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let month = today().month, day = today().day;
console.log(month, day); // 6 2
The old way
The new way
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let {m: month, d: day} = today();
console.log(month, day); // 6 2
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let month = today().month, day = today().day;
console.log(month, day); // 6 2
The old way
The new way
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let {m: month, d: day} = today();
console.log(month, day); // 6 2
console.log(m, d); // ReferenceError
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let month = today().month, day = today().day;
console.log(month, day); // 6 2
The old way
The new way
function today() {
return {
month: 6,
day: 2,
year: 2015
};
}
let {m: month, d: day} = today();
console.log(month, day); // 6 2
console.log(m, d); // ReferenceError
let {month, day} = today();
console.log(month, day); // 6 2
function today() {
return [6,2,2015];
}
let month = today()[0], day = today()[1];
console.log(month, day); // 6 2
The old way
function today() {
return [6,2,2015];
}
let month = today()[0], day = today()[1];
console.log(month, day); // 6 2
The old way
The new way
function today() {
return [6,2,2015];
}
let [month, day] = today();
console.log(month, day); // 6 2
The old way
function createPerson() {
let name="Martin", age=28;
return {
name: name,
age: age
};
}
The old way
function createPerson() {
let name="Martin", age=28;
return {
name: name,
age: age
};
}
The new way
function createPerson() {
let name="Martin", age=28;
return {
name,
age
};
}
The old way
function createPerson() {
let name="Martin", age=28;
return {
name: name,
age: age
};
}
The new way
function createPerson() {
let name="Martin", age=28;
return {
name,
age
};
}
function createPerson() {
var name="Martin", age=28;
return {
fullName: name,
age
};
}
The old way
var person = {
name: "Martin",
sayName: function() {
console.log(this.name);
}
};
The old way
var person = {
name: "Martin",
sayName: function() {
console.log(this.name);
}
};
The new way
var person = {
name: "Martin",
sayName() {
console.log(this.name);
}
};
let name = "Martin";
let greeting = "Hello " + name + "!";
The old way
let name = "Martin";
let greeting = "Hello " + name + "!";
The old way
The new way
let name = "Martin";
let greeting = `Hello ${name}!`;
let name = "Martin";
let greeting = "Hello " + name + "!";
The old way
The new way
let name = "Martin";
let greeting = `Hello ${name}!`;
function upper(s) {
return s.toUpperCase();
}
var text = `Hello ${upper( "martin" )}!`
console.log( text ); // Hello MARTIN!
Any valid expression is allowed
The old way
let message = [
"Multiline ",
"string"
].join("");
let message = "Multiline " +
"string";
The old way
The new way
let message = `Multiline
string`;
console.log(message.length); // 16
let message = [
"Multiline ",
"string"
].join("");
let message = "Multiline " +
"string";
The old way
The new way
let message = `Multiline
string`;
console.log(message.length); // 16
// all whitespace inside of the backticks
// is considered to be part of the string
let message = `Multiline
string`;
console.log(message.length); // 32
let message = [
"Multiline ",
"string"
].join("");
let message = "Multiline " +
"string";
Replaces:
// loops over the keys/indexes in the a array
var a = ["a","b","c","d","e"];
for(var idx in a){
console.log( idx );
}
// 0 1 2 3 4
Replaces:
// loops over the keys/indexes in the a array
var a = ["a","b","c","d","e"];
for(var idx in a){
console.log( idx );
}
// 0 1 2 3 4
Replaces:
// loops over the values in the a array
var a = ["a","b","c","d","e"];
for(var val of a){
console.log( val );
}
// "a" "b" "c" "d" "e"
function foo(x,y) {
return x + y;
}
The old way
function foo(x,y) {
return x + y;
}
The old way
The new way
var foo = (x,y) => x + y;
function foo(x,y) {
return x + y;
}
The old way
The new way
var foo = (x,y) => x + y;
Arrow function variations
var f1 = () => 12;
var f2 = x => x * 2;
var f3 = (x,y) => {
var z = x * 2 + y;
y++;
x *=3;
return (x + y + z) / 2;
};
function Thing() {
this.things = [1, 2, 3];
this.squaredThings = this.things.map(function(x) {
return this.square(x);
}.bind(this));
}
Thing.prototype.square = function(n) {
return n * n;
}
The old way
function Thing() {
this.things = [1, 2, 3];
this.squaredThings = this.things.map(function(x) {
return this.square(x);
}.bind(this));
}
Thing.prototype.square = function(n) {
return n * n;
}
The old way
The new way
function Thing() {
this.things = [1, 2, 3];
this.squaredThings = this.things.map(x => this.square(x));
}
Thing.prototype.square = function(n) {
return n * n;
}
let m = new Map();
m.set("hello", 42);
m.get("hello");
let m = new Map();
m.set("hello", 42);
m.get("hello");
// create an object
const Person = {
name: "Martin"
}
// add the complex key
m.set(Person, "present");
// get the value
console.log(m.get(Person)); // present
let m = new Map();
m.set("hello", 42);
m.get("hello");
// create an object
const Person = {
name: "Martin"
}
// add the complex key
m.set(Person, "present");
// get the value
console.log(m.get(Person)); // present
// iterable
for (let value of m.values()) {
console.log("value: " + value);
}
for (let key of m.keys()) {
console.log("key: " + JSON.stringify(key));
}
for (let [key,value] of m) {
console.log(key, value);
}
let s = new Set();
s.add("hello");
let s = new Set();
s.add("hello");
// create an object
const Person = {
name: "Charlie"
}
// add the complex value
s.add(Person);
// get the value
s.has(Person) === true;
let s = new Set();
s.add("hello");
// create an object
const Person = {
name: "Charlie"
}
// add the complex value
s.add(Person);
// get the value
s.has(Person) === true;
// try re-add the same value, ignored
s.add(Person);
let s = new Set();
s.add("hello");
// create an object
const Person = {
name: "Charlie"
}
// add the complex value
s.add(Person);
// get the value
s.has(Person) === true;
// try re-add the same value, ignored
s.add(Person);
// iterable
for (var item of s) {
console.log(item);
}
function someLongTask() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("someLongTask");
}, 1000);
});
}
function someOtherLongTask(msg) {
return new Promise(function(resolve,reject) {
setTimeout(function(){
resolve("someOtherLongTask says: " + msg);
}, 1500);
});
}
Producing a promise
function someLongTask() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("someLongTask");
}, 1000);
});
}
function someOtherLongTask(msg) {
return new Promise(function(resolve,reject) {
setTimeout(function(){
resolve("someOtherLongTask says: " + msg);
}, 1500);
});
}
Producing a promise
Consuming a promise
someLongTask()
.then(function (msg) {
console.log("Single: " + msg);
})
.catch(function (reason) {
console.error("Error: ", reason);
});
someLongTask()
.then(someOtherLongTask)
.then(function (msg) {
console.log("Chained: " + msg);
});
Chaining a promise
someLongTask()
.then(someOtherLongTask)
.then(function (msg) {
console.log("Chained: " + msg);
});
Chaining a promise
Promise.all
var promises = [someLongTask(), someOtherLongTask("Hello")];
Promise.all(promises).then(function(results) {
var msg1 = results[0];
var msg2 = results[1];
console.log("All: " + msg1+ " then "+ msg2);
});
someLongTask()
.then(someOtherLongTask)
.then(function (msg) {
console.log("Chained: " + msg);
});
Chaining a promise
Promise.all
var promises = [someLongTask(), someOtherLongTask("Hello")];
Promise.all(promises).then(function(results) {
var msg1 = results[0];
var msg2 = results[1];
console.log("All: " + msg1+ " then "+ msg2);
});
Tip: for large application use Bluebird promise as it's faster then native promise (native promise vs bluebird promise)
function *foo () { ... }
A generator is defined by an * character and can be paused and resumed at any time in your app
function *foo () { ... }
A generator is defined by an * character and can be paused and resumed at any time in your app
A generator function is paused by executing a yield keyword in the body of the function
function *foo () { yield 'bar'; }
function *foo () { ... }
A generator is defined by an * character and can be paused and resumed at any time in your app
A generator function is paused by executing a yield keyword in the body of the function
function *foo () { yield 'bar'; }
When a generator function is called, it returns a Generator Iterator object
var iterator = foo();
function *foo () { ... }
A generator is defined by an * character and can be paused and resumed at any time in your app
A generator function is paused by executing a yield keyword in the body of the function
function *foo () { yield 'bar'; }
When a generator function is called, it returns a Generator Iterator object
var iterator = foo();
The Generator Iterator includes a next() method for stepping through the generator function and next() method returns an object with ‘value’ and ‘done’ properties.
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
// create and iterator object
let myFoo = foo();
// console output
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
// create and iterator object
let myFoo = foo();
// executes foo until the first yield statement and return 1
console.log(myFoo.next());
// console output
execution starts
Object {value: "one", done: false}
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
// create and iterator object
let myFoo = foo();
// executes foo until the first yield statement and return 1
console.log(myFoo.next());
console.log(myFoo.next());
// console output
execution starts
Object {value: "one", done: false}
Object {value: "two", done: false}
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
// create and iterator object
let myFoo = foo();
// executes foo until the first yield statement and return 1
console.log(myFoo.next());
console.log(myFoo.next());
console.log(myFoo.next());
// console output
execution starts
Object {value: "one", done: false}
Object {value: "two", done: false}
Object {value: "three", done: false}
function *foo() {
console.log('execution starts');
yield 'one';
yield 'two';
yield 'three';
console.log('execution completes');
}
// create and iterator object
let myFoo = foo();
// executes foo until the first yield statement and return 1
console.log(myFoo.next());
console.log(myFoo.next());
console.log(myFoo.next());
console.log(myFoo.next());
// console output
execution starts
Object {value: "one", done: false}
Object {value: "two", done: false}
Object {value: "three", done: false}
execution completes
Object {value: undefined, done: true}
var restaurant = function(complete) {
takeOrder(['fish', 'sandwich', 'pizza'], function(err, order) {
});
};
var restaurant = function(complete) {
takeOrder(['fish', 'sandwich', 'pizza'], function(err, order) {
cookFood(order, function(err, meals) {
});
});
};
var restaurant = function(complete) {
takeOrder(['fish', 'sandwich', 'pizza'], function(err, order) {
cookFood(order, function(err, meals) {
if(err) {
console.log(err.message);
complete(err);
} else {
}
});
});
};
var restaurant = function(complete) {
takeOrder(['fish', 'sandwich', 'pizza'], function(err, order) {
cookFood(order, function(err, meals) {
if(err) {
console.log(err.message);
complete(err);
} else {
eat(meals[0], );
eat(meals[1], );
eat(meals[2], );
}
});
});
};
var restaurant = function(complete) {
takeOrder(['fish', 'sandwich', 'pizza'], function(err, order) {
cookFood(order, function(err, meals) {
if(err) {
console.log(err.message);
complete(err);
} else {
var counter = 3;
var payment = 0;
var waitForCustomer = function(err, money) {
counter--;
payment += money;
if(counter < 1) {
complete(null, payment);
}
};
eat(meals[0], waitForCustomer);
eat(meals[1], waitForCustomer);
eat(meals[2], waitForCustomer);
}
});
});
};
var restaurant = function() {
return takeOrder(['fish', 'sandwich', 'pizza'])
.then(function(order) {
return cookFood(order);
})
.then(function(meals) {
return Promise.all([eat(meals[0]), eat(meals[1]), eat(meals[2])]);
}, function(err) {
console.log(err.message);
return Promise.reject(err);
})
.then(function(monies) {
var total = 0;
monies.forEach(function(r){ total += r; });
return total;
});
};
var restaurant = function *() {
var order = yield takeOrder(['fish', 'sandwich', 'pizza']);
var meals = yield cookFood(order);
var total = 0;
var monies = yield Promise.all([eat(meals[0]), eat(meals[1]), eat(meals[2])]);
monies.forEach(function(r){ total += r; });
yield Promise.resolve(total);
};
var restaurant = function *() {
var order = yield takeOrder(['fish', 'sandwich', 'pizza']);
try {
var meals = yield cookFood(order);
var total = 0;
var monies = yield Promise.all([eat(meals[0]), eat(meals[1]), eat(meals[2])]);
monies.forEach(function(r){ total += r; });
yield Promise.resolve(total);
} catch(err) {
console.log(err.message);
}
};
var async = Bluebird.coroutine;
var restaurant = async(function *() {
var order = yield takeOrder(['fish', 'sandwich', 'pizza']);
try {
var meals = yield cookFood(order);
var total = 0;
var monies = yield Promise.all([eat(meals[0]), eat(meals[1]), eat(meals[2])]);
monies.forEach(function(r){ total += r; });
yield Promise.resolve(total);
} catch(err) {
console.log(err.message);
}
});
var restaurant = async function() {
var order = await takeOrder(['fish', 'sandwich', 'pizza']);
try {
var meals = await cookFood(order);
var total = 0;
var monies = await Promise.all([eat(meals[0]), eat(meals[1]), eat(meals[2])]);
monies.forEach(function(r){ total += r; });
return total;
} catch(err) {
console.log(err.message);
}
};
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.displayName = function() {
return this.firstName + " " + this.lastName;
}
var person = new Person("Martin", "Micunda");
console.log(person.displayName()); // Martin Micunda
The old way
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.displayName = function() {
return this.firstName + " " + this.lastName;
}
var person = new Person("Martin", "Micunda");
console.log(person.displayName()); // Martin Micunda
The old way
The new way
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
displayName() {
return `${this.firstName} ${this.lastName}`;
}
}
let person = new Person("Martin", "Micunda");
console.log(person.displayName()); // Martin Micunda
function Employee(firstName, lastName, employeeId) {
Person.call(this, firstName, lastName);
this.employeeId = employeeId;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.describe = function() {
return Person.prototype.displayName.call(this)
+ " (ID: " + this.employeeId + ")";
}
let employee = new Employee("Martin", "Micunda", 1234);
console.log(employee.describe()); // Martin Micunda (ID: 1234)
The old way
function Employee(firstName, lastName, employeeId) {
Person.call(this, firstName, lastName);
this.employeeId = employeeId;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.describe = function() {
return Person.prototype.displayName.call(this)
+ " (ID: " + this.employeeId + ")";
}
let employee = new Employee("Martin", "Micunda", 1234);
console.log(employee.describe()); // Martin Micunda (ID: 1234)
The old way
The new way
class Employee extends Person {
constructor(firstName, lastName, employeeId) {
super(firstName, lastName);
this.employeeId = employeeId;
}
describe() {
return `${super.displayName()} (ID: ${this.employeeId})`;
}
}
let employee = new Employee("Martin", "Micunda", 1234);
console.log(employee.describe()); // Martin Micunda (ID: 1234)
Screenshots taken from Kyle Simpson’s Advanced JavaScript course on Frontend Masters
Kyle Simpson OLOO
Eric Elliot Factories
Douglas Crockford
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
}
let person = person({firstName:'Martin', lastName: 'Micunda');
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
}
let person = person({firstName:'Martin', lastName: 'Micunda');
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
// expose public API
return Object.freeze({
firstName,
displayName
});
}
let person = person({firstName:'Martin', lastName: 'Micunda');
console.log(person.displayName()); // Martin Micunda
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
// expose public API
return Object.freeze({
firstName,
displayName
});
}
let person = person({firstName:'Martin', lastName: 'Micunda');
console.log(person.displayName()); // Martin Micunda
function employee(spec) {
let {employeeId} = spec;
}
let martin = employee({firstName:'Martin', lastName: 'Micunda', employeeId: 1234});
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
// expose public API
return Object.freeze({
firstName,
displayName
});
}
let person = person({firstName:'Martin', lastName: 'Micunda');
console.log(person.displayName()); // Martin Micunda
function employee(spec) {
let {employeeId} = spec;
// composition with other objects
// you can select only the parts that you want to use
// you only "inherit" the stuff that you need
let {displayName} = person(spec);
}
let martin = employee({firstName:'Martin', lastName: 'Micunda', employeeId: 1234});
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
// expose public API
return Object.freeze({
firstName,
displayName
});
}
let person = person({firstName:'Martin', lastName: 'Micunda');
console.log(person.displayName()); // Martin Micunda
function employee(spec) {
let {employeeId} = spec;
// composition with other objects
// you can select only the parts that you want to use
// you only "inherit" the stuff that you need
let {displayName} = person(spec);
let describe = function() {
return `${displayName()} (ID: ${employeeId})`;
}
}
let martin = employee({firstName:'Martin', lastName: 'Micunda', employeeId: 1234});
function person(spec) {
// initialize own members from spec
let {firstName, lastName} = spec;
// members methods
let displayName = function() {
return `${firstName} ${lastName}`;
};
// expose public API
return Object.freeze({
firstName,
displayName
});
}
let person = person({firstName:'Martin', lastName: 'Micunda');
console.log(person.displayName()); // Martin Micunda
function employee(spec) {
let {employeeId} = spec;
// composition with other objects
// you can select only the parts that you want to use
// you only "inherit" the stuff that you need
let {displayName} = person(spec);
let describe = function() {
return `${displayName()} (ID: ${employeeId})`;
}
return Object.freeze({
employeeId,
describe
});
}
let martin = employee({firstName:'Martin', lastName: 'Micunda', employeeId: 1234});
console.log(employee.describe()); // Martin Micunda (ID: 1234)
The Two Pillars of JavaScript by Eric Elliott
Common Misconceptions About Inheritance in JavaScript by Eric Elliott
How to Fix the ES6 `class` keyword by Eric Elliott
JS Objects: De”construct”ion by Kyle Simpson
Crockford’s 2014 Object Creation Pattern - Nordic.js 2014
The replacement for the AMD and CommonJS module formats.
The replacement for the AMD and CommonJS module formats.
Compact like CommonJS, async like AMD
The replacement for the AMD and CommonJS module formats.
Compact like CommonJS, async like AMD
The ES6 Specification defines two primary module features:
module syntax
module loader
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
//------ myFunc.js ------
export default function () { ... };
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
//------ myFunc.js ------
export default function () { ... };
//------ main1.js ------
import myFunc from 'myFunc';
myFunc()
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
//------ myFunc.js ------
export default function () { ... };
//------ main1.js ------
import myFunc from 'myFunc';
myFunc()
//------ MyClass.js ------
export default class { ... };
//------ main2.js ------
import MyClass from 'MyClass';
let inst = new MyClass();
//------ module.js ------
export function square(x) {
return x * x;
}
//------ index.js ------
System.import('module')
.then(module => {
console.log(module.square(5));
})
.catch(error => {
console.log(error);
});
Always bet on JS
Will include: