SlideShare une entreprise Scribd logo
1  sur  164
Télécharger pour lire hors ligne
ES6 Patterns in the Wild
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
Code to Run
(wild code)
Code to Run
(wild code)
Code we write Code we import
Code to Run
(wild code)
Code we write Code we import
$$
Code to Teach
Code to Teach
Tutorials
Code to Teach
Tutorials
Documentation
Style Guides
Stack Overflow
Books
Conferences
Code to Teach
Tutorials
Documentation
Style Guides
Stack Overflow
Books
Conferences
Good Stuff
Syntax
SELECT ID, NAME, AGE, AMOUNT
FROM CUSTOMERS, ORDERS
WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Unreadable
Pattern
Complexity
What we
expect
What we
get
Code to Teach
Code to Run
Code to Teach
Code to Run
Simple
Complex
Complex
Simple
Joe Morgan
Lawrence, KS
I Write Code
Joe Morgan
Joe Morgan
Read
Joe Morgan
Read
Read
Critically
Reading Code
Redux
{
donuts: [
“chocolate”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate </h2>
State Component
{
donuts: [
“chocolate”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate </h2>
State Component
dispatch(addDonut(‘maple’))
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate </h2>
State Component
dispatch(addDonut(‘maple’))
updated state
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate </h2>
State Component
dispatch(addDonut(‘maple’))
updated state
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate </h2>
<h2> Maple </h2>
State Component
dispatch(addDonut(‘maple’))
Redux
Functional
Array Methods
High Order Functions
Curry/Partially Applied
Functions
Redux
updated state
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut =>
{
return (
<h2> {{donut}} </h2>
)
}
<h2> Chocolate </h2>
<h2> Maple </h2>
State Component
dispatch(addDonut(‘maple’))
Middleware
Middleware
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch
var chain = []
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
}
}
Arrow Functions
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
}
}
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return function(createStore) {
return function (reducer, preloadedState, enhancer) {
var middlewareAPI = {
getState: store.getState,
dispatch: function (action) {
return dispatch(action);
}
}
chain = middlewares.map(function(middleware) {
return middleware(middlewareAPI)
})
}
}
}
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
}
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
chain = middlewares.map(middleware => middleware(middlewareAPI))
chain = middlewares.map((middleware) => {return middleware(middlewareAPI)})
var that = this;
var namer = {
name: 'bill',
say: function() {
var that = this
console.log(this.name);
setTimeout(function() {
console.log(that.name);
},200);
}
}
var that = this;
const namer = {
name: 'bill',
say: function() {
console.log(this.name);
setTimeout(() => {
console.log(this.name);
},200);
}
}
Favor Arrow Functions
Why Read Wild Code?
i. Reading Code is a Skill
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
i. Reading Code is a Skill: Intuition
i. Reading Code is a Skill: Intuition
i. Reading Code is a Skill: Intuition
Redux
Rest/Spread
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
}
}
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
}
}
(I actually didn’t realize they had different names)
Redux
Rest/Spread
Rest:
list => array
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
}
}
export default function applyMiddleware(...middlewares)
examples/real-world/src/store/configureStore.dev.js
applyMiddleware(thunk, api, createLogger())
examples/real-world/src/store/configureStore.prod.js
applyMiddleware(thunk, api)
Redux
Rest/Spread
Spread:
array => list
export default function applyMiddleware(...middlewares) {
dispatch = compose(...chain)(store.dispatch)
examples/real-world/src/store/configureStore.dev.js
compose(thunk, api, createLogger())(store.dispatch)
examples/real-world/src/store/configureStore.prod.js
compose(thunk, api)(store.dispatch)
Redux
Rest/Spread
Convert items to arrays
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
}
}
export default function applyMiddleware(...middlewares) {
// Lots of stuff
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
}
}
Redux
Rest/Spread
Converting array to a new array
without mutations
describe('combineReducers', () => {
it('returns a composite reducer that maps the state keys
to given reducers', () => {
const reducer = combineReducers({
...
action.type === 'push' ? [ ...state, action.value ] :
state
})
describe('combineReducers', () => {
it('returns a composite reducer that maps the state keys
to given reducers', () => {
const reducer = combineReducers({
...
action.type === 'push' ? [ ...state, action.value ] :
state
})
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
> family.sort(sortAge);
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
[
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
> family.sort(sortName);
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
[
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
> family.sort(sortAge);
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
[
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
]
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
> [...family].sort(sortAge);
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
[
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) => {
return a.name > b.name ? 1 : -1
}
const sortAge = (a, b) => {
if(a.age === b.age) {
return 0;
}
return a.age > b.age ? 1 : -1
}
ii. Your code will reflect your reading
ii. Your code will reflect your reading
data structures
architecture
community standards
ii. Your code will reflect your reading
It’s ok to take ideas
from others
ii. Your code will reflect your reading
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch
var chain = []
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch
var chain = []
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
Redux
Object Spread
Not part of ES6
//.babelrc
{
"plugins": [
...
"transform-object-rest-spread",
],
...
}
Favor Arrow Functions
Favor Array Methods
(map, reduce, find, filter)
Collecting items to arrays
+
Arrow Functions
=
Happiness
Khan Academy
Khan Academy
Consumer code. Not a library.
Khan Academy
Khan Academy
Object Oriented
Complexity hidden behind interface
Popular in typescript (angular 2) world
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
toJSON() {
return {
...super.toJSON(),
children: [...f(this.children).map(child => child.toJSON())],
};
}
clone(uniqueId = false) {
...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
toJSON() {
return {
...super.toJSON(),
children: [...f(this.children).map(child => child.toJSON())],
};
}
clone(uniqueId = false) {
...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
toJSON() {
return {
...super.toJSON(),
children: [...f(this.children).map(child => child.toJSON())],
};
}
clone(uniqueId = false) {
...
iii. Feature Popularity
iii. Feature Popularity: Frequency
The more useful the feature the more frequent it will pop up.
iii. Feature Popularity: Frequency
In Shakespeare:
The top 10 most frequently occuring words make up 21.4%
of all words.


The top 100 most frequently occuring words make up 53.9%
of all words.
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
toJSON() {
return {
...super.toJSON(),
children: [...f(this.children).map(child => child.toJSON())],
};
}
clone(uniqueId = false) {
...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
get last() {
return this.children.last;
}
set last(value) {
this.children.last = value;
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
Linked List
Khan Academy
export default class Expression extends Node {
get last() {
return this.children.last;
}
set last(value) {
this.children.last = value;
}
}
Get/Set treats methods like
properties (popular in
typescript)
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
e.last;
// { id: 3 }
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
e.last = { id.4 }
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 4
}
}
}
e.last = { id.4 }
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 4
}
}
}
e.last = { id.4 }
export default class Expression extends Node {
get last() {
return this.children.last;
}
set last(value) {
this.children.last = value;
}
}
export default class Expression extends Node {
get last() {
return Object.assign(
{}, { name:'last' }, this.children.last
);
}
set last(value) {
this.children.last = value;
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
e.last
{
name: ‘last’,
id: 3,

}
export default class Expression extends Node {
constructor(...nodes) {
super();
this.children = new List(this, ...nodes);
}
toString() {
return `${this.type}:${this.children.toString()}`;
}
get first() {
return this.children.first;
}
set first(value) {
this.children.first = value;
}
}
export default class Expression extends Node {
toString() {
return `${this.type}:${this.children.toString()}`;
}
}
export default class Expression extends Node {
toString() {
return this.type + ':' + this.children.toString();
}
}
export default class List extends Node {
...
toString() {
let first = true;
for (let node of this) {
if (!first) {
result += ", ";
} else {
first = false;
}
result += node.id;
}
return result;
}
}
export default class List extends Node {
...
toString() {
let first = true;
for (let node of this) {
// Do Stuff with node.id
}
}
}
export default class List extends Node {
...
toString() {
let first = true;
for (let node of this) {
// Do Stuff with node.id
}
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
const presentation = [
'ES6 Patterns in the Wild',
'Joe Morgan',
]
for(let metadata of presentation) {
console.log(metadata);
}
const presentation = [
'ES6 Patterns in the Wild',
'Joe Morgan',
]
for(let metadata of presentation) {
console.log(metadata);
}
// ES 6 Patterns in the Wild
// Joe Morgan
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
for(let metadata of presentation) {
console.log(metadata);
}
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
for(let metadata of presentation) {
console.log(metadata);
}
> TypeError: presentation[Symbol.iterator] is not a function
export default class List {
...
*[Symbol.iterator]() {
let node = this.first;
while (node != this.last) {
let current = node;
node = node.next;
yield current;
}
if (this.last) {
yield this.last;
}
}
}
export default class List {
...
*[Symbol.iterator]() {
let node = this.first;
while (node != this.last) {
let current = node;
node = node.next;
yield current;
}
if (this.last) {
yield this.last;
}
}
}
iii. Feature Popularity:
Not all features end up being popular
iii. Feature Popularity:
Not all features end up being popular
export default class List {
...
*[Symbol.iterator]() {
let node = this.first;
while (node != this.last) {
let current = node;
node = node.next;
yield current;
}
if (this.last) {
yield this.last;
}
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
last: {
id: 3
}
}
}
const e = new Expression({id:1}, {id:2}, {id:3})
e = [{id:1}, {id:2}, {id:3}]
Khan Academy
Create Simple Interfaces
React
React
Performance
canUseCollections = (
...
typeof Map === 'function' &&
isNative(Map) &&
...
);
if (canUseCollections) {
var itemMap = new Map();
var rootIDSet = new Set();
setItem = function(id, item) {
itemMap.set(id, item);
};
getItem = function(id) {
return itemMap.get(id);
};
...
}
else {
var itemByKey = {};
var rootByKey = {};
var getKeyFromID = () => {}
var getIDFromKey = () => {}
setItem = function(id, item) {
var key = getKeyFromID(id);
itemByKey[key] = item;
};
getItem = function(id) {
var key = getKeyFromID(id);
return itemByKey[key];
};
...
}
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
> presentation.title
// 'ES6 Patterns in the Wild'
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
> presentation.title
// 'ES6 Patterns in the Wild'
const presentation = new Map();
presentation.set('title', 'ES6 Patterns in
the Wild');
presentation.set('author', 'Joe Morgan');
> presentation.get('title');
// 'ES6 Patterns in the Wild'
const presentation = new Map()
.set('title', 'ES6 Patterns in the Wild')
.set('author', 'Joe Morgan');
> presentation.get('title');
// 'ES6 Patterns in the Wild'
const presentation = new Map([
['title', 'ES6 Patterns in the Wild'],
['author', 'Joe Morgan']
]);
> presentation.get('title');
// 'ES6 Patterns in the Wild'
canUseCollections = (
...
typeof Map === 'function' &&
isNative(Map) &&
...
);
if (canUseCollections) {
var itemMap = new Map();
var rootIDSet = new Set();
setItem = function(id, item) {
itemMap.set(id, item);
};
getItem = function(id) {
return itemMap.get(id);
};
...
}
else {
var itemByKey = {};
var rootByKey = {};
var getKeyFromID = () => {}
var getIDFromKey = () => {}
setItem = function(id, item) {
var key = getKeyFromID(id);
itemByKey[key] = item;
};
getItem = function(id) {
var key = getKeyFromID(id);
return itemByKey[key];
};
...
}
React
React
React
As ES6 becomes native there
are advantages beyond style
Build a Library of Readable Code
Lurk Around Github
Lurk Around Github
Advanced Search
Glance at your dependencies
Have a few authors you like
iv. Code can be beautiful
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
var data = [1,2,3,4];
var updated = [];
for(var i = 0; i < data.length; i++) {
updated.push(i*i);
}
return updated;
const data = [1,2,3,4];
return data.map(n => n*n);
Perfection is finally attained not
when there is no longer anything
to add, but when there is no
longer anything to take away
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
Joe Morgan
Joe Morgan
@joesmorgan
Joe Morgan
@joesmorgan
thejoemorgan.com
Joe Morgan
@joesmorgan
thejoemorgan.com
https://github.com/jsmapr1

Contenu connexe

Tendances

Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12
jafar104
 
Html5 game programming overview
Html5 game programming overviewHtml5 game programming overview
Html5 game programming overview
민태 김
 

Tendances (20)

스위프트를 여행하는 히치하이커를 위한 스타일 안내
스위프트를 여행하는 히치하이커를 위한 스타일 안내스위프트를 여행하는 히치하이커를 위한 스타일 안내
스위프트를 여행하는 히치하이커를 위한 스타일 안내
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6
 
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.10 book - Part 70 of 212
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
mobl
moblmobl
mobl
 
CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
The evolution of redux action creators
The evolution of redux action creatorsThe evolution of redux action creators
The evolution of redux action creators
 
Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12
 
Hidden rocks in Oracle ADF
Hidden rocks in Oracle ADFHidden rocks in Oracle ADF
Hidden rocks in Oracle ADF
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Html5 game programming overview
Html5 game programming overviewHtml5 game programming overview
Html5 game programming overview
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Method::Signatures
Method::SignaturesMethod::Signatures
Method::Signatures
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 

Similaire à ES6 patterns in the wild

Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
MongoSF
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
Morgan Cheng
 
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdfJAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
calderoncasto9163
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
Darwin Durand
 

Similaire à ES6 patterns in the wild (20)

TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
 
Build Lightweight Web Module
Build Lightweight Web ModuleBuild Lightweight Web Module
Build Lightweight Web Module
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdfJAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
JAVA...With N.E.T_B.E.A.N.S___________________________________.pdf
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
Kamil Chmielewski, Jacek Juraszek - "Hadoop. W poszukiwaniu złotego młotka."
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
React lecture
React lectureReact lecture
React lecture
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 

Plus de Joe Morgan (6)

Git the easy way
Git the easy wayGit the easy way
Git the easy way
 
React Animations
React AnimationsReact Animations
React Animations
 
Reference Interviews: Where the fun never ends
Reference Interviews: Where the fun never endsReference Interviews: Where the fun never ends
Reference Interviews: Where the fun never ends
 
Statement of Teaching Philosophy
Statement of Teaching PhilosophyStatement of Teaching Philosophy
Statement of Teaching Philosophy
 
Option 2
Option 2Option 2
Option 2
 
Library Committee Meeting
Library Committee MeetingLibrary Committee Meeting
Library Committee Meeting
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 

ES6 patterns in the wild

  • 1. ES6 Patterns in the Wild
  • 2. function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
  • 4. Code to Run (wild code) Code we write Code we import
  • 5. Code to Run (wild code) Code we write Code we import $$
  • 8. Code to Teach Tutorials Documentation Style Guides Stack Overflow Books Conferences
  • 9. Code to Teach Tutorials Documentation Style Guides Stack Overflow Books Conferences Good Stuff
  • 10. Syntax SELECT ID, NAME, AGE, AMOUNT FROM CUSTOMERS, ORDERS WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
  • 22.
  • 28. Redux
  • 29. { donuts: [ “chocolate”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component
  • 30. { donuts: [ “chocolate”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  • 31. { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  • 32. updated state { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  • 33. updated state { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> <h2> Maple </h2> State Component dispatch(addDonut(‘maple’))
  • 34. Redux Functional Array Methods High Order Functions Curry/Partially Applied Functions
  • 35. Redux
  • 36. updated state { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) } <h2> Chocolate </h2> <h2> Maple </h2> State Component dispatch(addDonut(‘maple’)) Middleware Middleware
  • 37. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer) var dispatch = store.dispatch var chain = [] var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
  • 38. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) } } Arrow Functions
  • 39. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) } }
  • 40. import compose from './compose' export default function applyMiddleware(...middlewares) { return function(createStore) { return function (reducer, preloadedState, enhancer) { var middlewareAPI = { getState: store.getState, dispatch: function (action) { return dispatch(action); } } chain = middlewares.map(function(middleware) { return middleware(middlewareAPI) }) } } }
  • 41. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) } }
  • 42. chain = middlewares.map(middleware => middleware(middlewareAPI))
  • 43. chain = middlewares.map(middleware => middleware(middlewareAPI)) chain = middlewares.map((middleware) => {return middleware(middlewareAPI)})
  • 44. var that = this;
  • 45. var namer = { name: 'bill', say: function() { var that = this console.log(this.name); setTimeout(function() { console.log(that.name); },200); } }
  • 46. var that = this;
  • 47. const namer = { name: 'bill', say: function() { console.log(this.name); setTimeout(() => { console.log(this.name); },200); } }
  • 49. Why Read Wild Code?
  • 50. i. Reading Code is a Skill
  • 51. function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
  • 52. i. Reading Code is a Skill: Intuition
  • 53. i. Reading Code is a Skill: Intuition
  • 54. i. Reading Code is a Skill: Intuition
  • 55. Redux Rest/Spread export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  • 56. export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } } (I actually didn’t realize they had different names)
  • 58. export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  • 59. export default function applyMiddleware(...middlewares) examples/real-world/src/store/configureStore.dev.js applyMiddleware(thunk, api, createLogger()) examples/real-world/src/store/configureStore.prod.js applyMiddleware(thunk, api)
  • 61. export default function applyMiddleware(...middlewares) { dispatch = compose(...chain)(store.dispatch) examples/real-world/src/store/configureStore.dev.js compose(thunk, api, createLogger())(store.dispatch) examples/real-world/src/store/configureStore.prod.js compose(thunk, api)(store.dispatch)
  • 63. export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  • 64. export default function applyMiddleware(...middlewares) { // Lots of stuff var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  • 65. Redux Rest/Spread Converting array to a new array without mutations
  • 66. describe('combineReducers', () => { it('returns a composite reducer that maps the state keys to given reducers', () => { const reducer = combineReducers({ ... action.type === 'push' ? [ ...state, action.value ] : state })
  • 67. describe('combineReducers', () => { it('returns a composite reducer that maps the state keys to given reducers', () => { const reducer = combineReducers({ ... action.type === 'push' ? [ ...state, action.value ] : state })
  • 68. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 69. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } > family.sort(sortAge);
  • 70. const family = [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ]
  • 71. const family = [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 72. const family = [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } > family.sort(sortName);
  • 73. const family = [ { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } [ { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, ]
  • 74. const family = [ { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 75. const family = [ { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } > family.sort(sortAge);
  • 76. const family = [ { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } [ { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, ]
  • 77. const family = [ { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, { name: 'Joe', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 78. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 79. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } > [...family].sort(sortAge);
  • 80. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 } [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ]
  • 81. const family = [ { name: 'Joe', age: 34 }, { name: 'Theo', age: 1 }, { name: 'Dyan', age: 34 }, ] const sortName = (a,b) => { return a.name > b.name ? 1 : -1 } const sortAge = (a, b) => { if(a.age === b.age) { return 0; } return a.age > b.age ? 1 : -1 }
  • 82. ii. Your code will reflect your reading
  • 83. ii. Your code will reflect your reading data structures architecture community standards
  • 84. ii. Your code will reflect your reading It’s ok to take ideas from others
  • 85. ii. Your code will reflect your reading
  • 86. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer) var dispatch = store.dispatch var chain = [] var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
  • 87. import compose from './compose' export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer) var dispatch = store.dispatch var chain = [] var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
  • 91. Favor Array Methods (map, reduce, find, filter)
  • 92. Collecting items to arrays + Arrow Functions = Happiness
  • 94. Khan Academy Consumer code. Not a library.
  • 96. Khan Academy Object Oriented Complexity hidden behind interface Popular in typescript (angular 2) world
  • 97.
  • 98. export default class Expression extends Node { constructor(...nodes) { super(); this.type = 'Expression'; this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } toJSON() { return { ...super.toJSON(), children: [...f(this.children).map(child => child.toJSON())], }; } clone(uniqueId = false) { ...
  • 99. export default class Expression extends Node { constructor(...nodes) { super(); this.type = 'Expression'; this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } toJSON() { return { ...super.toJSON(), children: [...f(this.children).map(child => child.toJSON())], }; } clone(uniqueId = false) { ...
  • 100. export default class Expression extends Node { constructor(...nodes) { super(); this.type = 'Expression'; this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } toJSON() { return { ...super.toJSON(), children: [...f(this.children).map(child => child.toJSON())], }; } clone(uniqueId = false) { ...
  • 102. iii. Feature Popularity: Frequency The more useful the feature the more frequent it will pop up.
  • 103. iii. Feature Popularity: Frequency In Shakespeare: The top 10 most frequently occuring words make up 21.4% of all words. 
 The top 100 most frequently occuring words make up 53.9% of all words.
  • 104. export default class Expression extends Node { constructor(...nodes) { super(); this.type = 'Expression'; this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } toJSON() { return { ...super.toJSON(), children: [...f(this.children).map(child => child.toJSON())], }; } clone(uniqueId = false) { ...
  • 105. export default class Expression extends Node { constructor(...nodes) { super(); this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } get last() { return this.children.last; } set last(value) { this.children.last = value; } }
  • 106. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  • 107. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } } Linked List
  • 109. export default class Expression extends Node { get last() { return this.children.last; } set last(value) { this.children.last = value; } }
  • 110. Get/Set treats methods like properties (popular in typescript)
  • 111. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  • 112. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } } e.last; // { id: 3 }
  • 113. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } } e.last = { id.4 }
  • 114. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 4 } } } e.last = { id.4 }
  • 115. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 4 } } } e.last = { id.4 }
  • 116. export default class Expression extends Node { get last() { return this.children.last; } set last(value) { this.children.last = value; } }
  • 117. export default class Expression extends Node { get last() { return Object.assign( {}, { name:'last' }, this.children.last ); } set last(value) { this.children.last = value; } }
  • 118. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } } e.last { name: ‘last’, id: 3,
 }
  • 119. export default class Expression extends Node { constructor(...nodes) { super(); this.children = new List(this, ...nodes); } toString() { return `${this.type}:${this.children.toString()}`; } get first() { return this.children.first; } set first(value) { this.children.first = value; } }
  • 120. export default class Expression extends Node { toString() { return `${this.type}:${this.children.toString()}`; } }
  • 121. export default class Expression extends Node { toString() { return this.type + ':' + this.children.toString(); } }
  • 122. export default class List extends Node { ... toString() { let first = true; for (let node of this) { if (!first) { result += ", "; } else { first = false; } result += node.id; } return result; } }
  • 123. export default class List extends Node { ... toString() { let first = true; for (let node of this) { // Do Stuff with node.id } } }
  • 124. export default class List extends Node { ... toString() { let first = true; for (let node of this) { // Do Stuff with node.id } } }
  • 125. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  • 126. const presentation = [ 'ES6 Patterns in the Wild', 'Joe Morgan', ] for(let metadata of presentation) { console.log(metadata); }
  • 127. const presentation = [ 'ES6 Patterns in the Wild', 'Joe Morgan', ] for(let metadata of presentation) { console.log(metadata); } // ES 6 Patterns in the Wild // Joe Morgan
  • 128. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } for(let metadata of presentation) { console.log(metadata); }
  • 129. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } for(let metadata of presentation) { console.log(metadata); } > TypeError: presentation[Symbol.iterator] is not a function
  • 130. export default class List { ... *[Symbol.iterator]() { let node = this.first; while (node != this.last) { let current = node; node = node.next; yield current; } if (this.last) { yield this.last; } } }
  • 131. export default class List { ... *[Symbol.iterator]() { let node = this.first; while (node != this.last) { let current = node; node = node.next; yield current; } if (this.last) { yield this.last; } } }
  • 132. iii. Feature Popularity: Not all features end up being popular
  • 133. iii. Feature Popularity: Not all features end up being popular
  • 134. export default class List { ... *[Symbol.iterator]() { let node = this.first; while (node != this.last) { let current = node; node = node.next; yield current; } if (this.last) { yield this.last; } } }
  • 135. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  • 136. const e = new Expression({id:1}, {id:2}, {id:3}) e = [{id:1}, {id:2}, {id:3}]
  • 138. React
  • 140. canUseCollections = ( ... typeof Map === 'function' && isNative(Map) && ... ); if (canUseCollections) { var itemMap = new Map(); var rootIDSet = new Set(); setItem = function(id, item) { itemMap.set(id, item); }; getItem = function(id) { return itemMap.get(id); }; ... } else { var itemByKey = {}; var rootByKey = {}; var getKeyFromID = () => {} var getIDFromKey = () => {} setItem = function(id, item) { var key = getKeyFromID(id); itemByKey[key] = item; }; getItem = function(id) { var key = getKeyFromID(id); return itemByKey[key]; }; ... }
  • 141. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } > presentation.title // 'ES6 Patterns in the Wild'
  • 142. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } > presentation.title // 'ES6 Patterns in the Wild'
  • 143. const presentation = new Map(); presentation.set('title', 'ES6 Patterns in the Wild'); presentation.set('author', 'Joe Morgan'); > presentation.get('title'); // 'ES6 Patterns in the Wild'
  • 144. const presentation = new Map() .set('title', 'ES6 Patterns in the Wild') .set('author', 'Joe Morgan'); > presentation.get('title'); // 'ES6 Patterns in the Wild'
  • 145. const presentation = new Map([ ['title', 'ES6 Patterns in the Wild'], ['author', 'Joe Morgan'] ]); > presentation.get('title'); // 'ES6 Patterns in the Wild'
  • 146. canUseCollections = ( ... typeof Map === 'function' && isNative(Map) && ... ); if (canUseCollections) { var itemMap = new Map(); var rootIDSet = new Set(); setItem = function(id, item) { itemMap.set(id, item); }; getItem = function(id) { return itemMap.get(id); }; ... } else { var itemByKey = {}; var rootByKey = {}; var getKeyFromID = () => {} var getIDFromKey = () => {} setItem = function(id, item) { var key = getKeyFromID(id); itemByKey[key] = item; }; getItem = function(id) { var key = getKeyFromID(id); return itemByKey[key]; }; ... }
  • 147. React
  • 148. React
  • 149. React As ES6 becomes native there are advantages beyond style
  • 150. Build a Library of Readable Code
  • 153. Glance at your dependencies
  • 154. Have a few authors you like
  • 155. iv. Code can be beautiful
  • 156. function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
  • 157. var data = [1,2,3,4]; var updated = []; for(var i = 0; i < data.length; i++) { updated.push(i*i); } return updated;
  • 158. const data = [1,2,3,4]; return data.map(n => n*n);
  • 159. Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away
  • 160. function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;