Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
ES6 Patterns in the Wild
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action =...
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 <...
{
donuts: [
“chocolate”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Chocolate <...
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2>
)
})
<h2> Ch...
updated state
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2...
updated state
{
donuts: [
“chocolate”,
“maple”,
],
filter: null
}
state.donuts.map(donut => {
return (
<h2> {{donut}} </h2...
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...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return function(createStore) {
r...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer...
chain = middlewares.map(middleware => middleware(middlewareAPI))
chain = middlewares.map(middleware => middleware(middlewareAPI))
chain = middlewares.map((middleware) => {return middlewar...
var that = this;
var namer = {
name: 'bill',
say: function() {
var that = this
console.log(this.name);
setTimeout(function() {
console.log(...
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 =...
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(middl...
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middlewar...
Redux
Rest/Spread
Rest:
list => array
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middlewar...
export default function applyMiddleware(...middlewares)
examples/real-world/src/store/configureStore.dev.js
applyMiddlewar...
Redux
Rest/Spread
Spread:
array => list
export default function applyMiddleware(...middlewares) {
dispatch = compose(...chain)(store.dispatch)
examples/real-world...
Redux
Rest/Spread
Convert items to arrays
export default function applyMiddleware(...middlewares) {
// Lots of stuff
chain = middlewares.map(middleware => middlewar...
export default function applyMiddleware(...middlewares) {
// Lots of stuff
var middlewareAPI = {
getState: store.getState,...
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', () => {
c...
describe('combineReducers', () => {
it('returns a composite reducer that maps the state keys
to given reducers', () => {
c...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Joe',
age: 34
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
{
name: 'Joe',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
const family = [
{
name: 'Joe',
age: 34
},
{
name: 'Theo',
age: 1
},
{
name: 'Dyan',
age: 34
},
]
const sortName = (a,b) =...
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...
import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer...
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 = ...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = ...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = ...
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.

...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.type = 'Expression';
this.children = ...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.children = new List(this, ...nodes);
...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
Khan Academy
export default class Expression extends Node {
get last() {
return this.children.last;
}
set last(value) {
this.children.l...
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
}
}
},
las...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
export default class Expression extends Node {
get last() {
return this.children.last;
}
set last(value) {
this.children.l...
export default class Expression extends Node {
get last() {
return Object.assign(
{}, { name:'last' }, this.children.last
...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
export default class Expression extends Node {
constructor(...nodes) {
super();
this.children = new List(this, ...nodes);
...
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 ...
export default class List extends Node {
...
toString() {
let first = true;
for (let node of this) {
// Do Stuff with node...
export default class List extends Node {
...
toString() {
let first = true;
for (let node of this) {
// Do Stuff with node...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
const presentation = [
'ES6 Patterns in the Wild',
'Joe Morgan',
]
for(let metadata of presentation) {
console.log(metadat...
const presentation = [
'ES6 Patterns in the Wild',
'Joe Morgan',
]
for(let metadata of presentation) {
console.log(metadat...
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
for(let metadata of presentation) {
cons...
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
for(let metadata of presentation) {
cons...
export default class List {
...
*[Symbol.iterator]() {
let node = this.first;
while (node != this.last) {
let current = no...
export default class List {
...
*[Symbol.iterator]() {
let node = this.first;
while (node != this.last) {
let current = no...
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 = no...
const e = new Expression({id:1}, {id:2}, {id:3})
e = {
children: {
first: {
id: 1,
next: {
id: 2,
next: {
id: 3
}
}
},
las...
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 ...
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
> presentation.title
// 'ES6 Patterns in...
const presentation = {
title: 'ES6 Patterns in the Wild',
author: 'Joe Morgan',
}
> presentation.title
// 'ES6 Patterns in...
const presentation = new Map();
presentation.set('title', 'ES6 Patterns in
the Wild');
presentation.set('author', 'Joe Mor...
const presentation = new Map()
.set('title', 'ES6 Patterns in the Wild')
.set('author', 'Joe Morgan');
> presentation.get(...
const presentation = new Map([
['title', 'ES6 Patterns in the Wild'],
['author', 'Joe Morgan']
]);
> presentation.get('tit...
canUseCollections = (
...
typeof Map === 'function' &&
isNative(Map) &&
...
);
if (canUseCollections) {
var itemMap = new ...
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 =...
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 a...
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action =...
Joe Morgan
Joe Morgan
@joesmorgan
Joe Morgan
@joesmorgan
thejoemorgan.com
Joe Morgan
@joesmorgan
thejoemorgan.com
https://github.com/jsmapr1
ES6 patterns in the wild
ES6 patterns in the wild
Upcoming SlideShare
Loading in …5
×

ES6 patterns in the wild

1,247 views

Published on

Talk delivered at Codemash 2017. The goal was to learn ES6 patterns by reading code found on GitHub.

Published in: Technology
  • Be the first to comment

ES6 patterns in the wild

  1. 1. ES6 Patterns in the Wild
  2. 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;
  3. 3. Code to Run (wild code)
  4. 4. Code to Run (wild code) Code we write Code we import
  5. 5. Code to Run (wild code) Code we write Code we import $$
  6. 6. Code to Teach
  7. 7. Code to Teach Tutorials
  8. 8. Code to Teach Tutorials Documentation Style Guides Stack Overflow Books Conferences
  9. 9. Code to Teach Tutorials Documentation Style Guides Stack Overflow Books Conferences Good Stuff
  10. 10. Syntax SELECT ID, NAME, AGE, AMOUNT FROM CUSTOMERS, ORDERS WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
  11. 11. Unreadable
  12. 12. Pattern
  13. 13. Complexity
  14. 14. What we expect
  15. 15. What we get
  16. 16. Code to Teach Code to Run
  17. 17. Code to Teach Code to Run
  18. 18. Simple Complex
  19. 19. Complex Simple
  20. 20. Joe Morgan
  21. 21. Lawrence, KS
  22. 22. I Write Code
  23. 23. Joe Morgan
  24. 24. Joe Morgan Read
  25. 25. Joe Morgan Read Read Critically
  26. 26. Reading Code
  27. 27. Redux
  28. 28. { donuts: [ “chocolate”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component
  29. 29. { donuts: [ “chocolate”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  30. 30. { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  31. 31. updated state { donuts: [ “chocolate”, “maple”, ], filter: null } state.donuts.map(donut => { return ( <h2> {{donut}} </h2> ) }) <h2> Chocolate </h2> State Component dispatch(addDonut(‘maple’))
  32. 32. 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’))
  33. 33. Redux Functional Array Methods High Order Functions Curry/Partially Applied Functions
  34. 34. Redux
  35. 35. 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
  36. 36. 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 } } }
  37. 37. 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
  38. 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)) } }
  39. 39. 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) }) } } }
  40. 40. 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)) } }
  41. 41. chain = middlewares.map(middleware => middleware(middlewareAPI))
  42. 42. chain = middlewares.map(middleware => middleware(middlewareAPI)) chain = middlewares.map((middleware) => {return middleware(middlewareAPI)})
  43. 43. var that = this;
  44. 44. var namer = { name: 'bill', say: function() { var that = this console.log(this.name); setTimeout(function() { console.log(that.name); },200); } }
  45. 45. var that = this;
  46. 46. const namer = { name: 'bill', say: function() { console.log(this.name); setTimeout(() => { console.log(this.name); },200); } }
  47. 47. Favor Arrow Functions
  48. 48. Why Read Wild Code?
  49. 49. i. Reading Code is a Skill
  50. 50. 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;
  51. 51. i. Reading Code is a Skill: Intuition
  52. 52. i. Reading Code is a Skill: Intuition
  53. 53. i. Reading Code is a Skill: Intuition
  54. 54. Redux Rest/Spread export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  55. 55. 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)
  56. 56. Redux Rest/Spread Rest: list => array
  57. 57. export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  58. 58. 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)
  59. 59. Redux Rest/Spread Spread: array => list
  60. 60. 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)
  61. 61. Redux Rest/Spread Convert items to arrays
  62. 62. export default function applyMiddleware(...middlewares) { // Lots of stuff chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) } }
  63. 63. 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) } }
  64. 64. Redux Rest/Spread Converting array to a new array without mutations
  65. 65. 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 })
  66. 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. 67. 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 }
  68. 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 } > family.sort(sortAge);
  69. 69. 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 }, ]
  70. 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 }
  71. 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 } > family.sort(sortName);
  72. 72. 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 }, ]
  73. 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 }
  74. 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 } > family.sort(sortAge);
  75. 75. 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 }, ]
  76. 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 }
  77. 77. 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 }
  78. 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 } > [...family].sort(sortAge);
  79. 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 } [ { name: 'Theo', age: 1 }, { name: 'Joe', age: 34 }, { name: 'Dyan', age: 34 }, ]
  80. 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 }
  81. 81. ii. Your code will reflect your reading
  82. 82. ii. Your code will reflect your reading data structures architecture community standards
  83. 83. ii. Your code will reflect your reading It’s ok to take ideas from others
  84. 84. ii. Your code will reflect your reading
  85. 85. 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 } } }
  86. 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. 87. Redux Object Spread Not part of ES6
  88. 88. //.babelrc { "plugins": [ ... "transform-object-rest-spread", ], ... }
  89. 89. Favor Arrow Functions
  90. 90. Favor Array Methods (map, reduce, find, filter)
  91. 91. Collecting items to arrays + Arrow Functions = Happiness
  92. 92. Khan Academy
  93. 93. Khan Academy Consumer code. Not a library.
  94. 94. Khan Academy
  95. 95. Khan Academy Object Oriented Complexity hidden behind interface Popular in typescript (angular 2) world
  96. 96. 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) { ...
  97. 97. 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) { ...
  98. 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. 99. iii. Feature Popularity
  100. 100. iii. Feature Popularity: Frequency The more useful the feature the more frequent it will pop up.
  101. 101. 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.
  102. 102. 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) { ...
  103. 103. 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; } }
  104. 104. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  105. 105. 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
  106. 106. Khan Academy
  107. 107. export default class Expression extends Node { get last() { return this.children.last; } set last(value) { this.children.last = value; } }
  108. 108. Get/Set treats methods like properties (popular in typescript)
  109. 109. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  110. 110. 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 }
  111. 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 } } } e.last = { id.4 }
  112. 112. 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 }
  113. 113. 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 }
  114. 114. export default class Expression extends Node { get last() { return this.children.last; } set last(value) { this.children.last = value; } }
  115. 115. export default class Expression extends Node { get last() { return Object.assign( {}, { name:'last' }, this.children.last ); } set last(value) { this.children.last = value; } }
  116. 116. 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,
 }
  117. 117. 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; } }
  118. 118. export default class Expression extends Node { toString() { return `${this.type}:${this.children.toString()}`; } }
  119. 119. export default class Expression extends Node { toString() { return this.type + ':' + this.children.toString(); } }
  120. 120. 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; } }
  121. 121. export default class List extends Node { ... toString() { let first = true; for (let node of this) { // Do Stuff with node.id } } }
  122. 122. export default class List extends Node { ... toString() { let first = true; for (let node of this) { // Do Stuff with node.id } } }
  123. 123. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  124. 124. const presentation = [ 'ES6 Patterns in the Wild', 'Joe Morgan', ] for(let metadata of presentation) { console.log(metadata); }
  125. 125. 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
  126. 126. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } for(let metadata of presentation) { console.log(metadata); }
  127. 127. 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
  128. 128. 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; } } }
  129. 129. 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; } } }
  130. 130. iii. Feature Popularity: Not all features end up being popular
  131. 131. iii. Feature Popularity: Not all features end up being popular
  132. 132. 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; } } }
  133. 133. const e = new Expression({id:1}, {id:2}, {id:3}) e = { children: { first: { id: 1, next: { id: 2, next: { id: 3 } } }, last: { id: 3 } } }
  134. 134. const e = new Expression({id:1}, {id:2}, {id:3}) e = [{id:1}, {id:2}, {id:3}]
  135. 135. Khan Academy Create Simple Interfaces
  136. 136. React
  137. 137. React Performance
  138. 138. 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]; }; ... }
  139. 139. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } > presentation.title // 'ES6 Patterns in the Wild'
  140. 140. const presentation = { title: 'ES6 Patterns in the Wild', author: 'Joe Morgan', } > presentation.title // 'ES6 Patterns in the Wild'
  141. 141. 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'
  142. 142. const presentation = new Map() .set('title', 'ES6 Patterns in the Wild') .set('author', 'Joe Morgan'); > presentation.get('title'); // 'ES6 Patterns in the Wild'
  143. 143. const presentation = new Map([ ['title', 'ES6 Patterns in the Wild'], ['author', 'Joe Morgan'] ]); > presentation.get('title'); // 'ES6 Patterns in the Wild'
  144. 144. 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]; }; ... }
  145. 145. React
  146. 146. React
  147. 147. React As ES6 becomes native there are advantages beyond style
  148. 148. Build a Library of Readable Code
  149. 149. Lurk Around Github
  150. 150. Lurk Around Github Advanced Search
  151. 151. Glance at your dependencies
  152. 152. Have a few authors you like
  153. 153. iv. Code can be beautiful
  154. 154. 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;
  155. 155. var data = [1,2,3,4]; var updated = []; for(var i = 0; i < data.length; i++) { updated.push(i*i); } return updated;
  156. 156. const data = [1,2,3,4]; return data.map(n => n*n);
  157. 157. Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away
  158. 158. 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;
  159. 159. Joe Morgan
  160. 160. Joe Morgan @joesmorgan
  161. 161. Joe Morgan @joesmorgan thejoemorgan.com
  162. 162. Joe Morgan @joesmorgan thejoemorgan.com https://github.com/jsmapr1

×