1 of 164

ES6 Patterns in the Wild

2 of 164

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 of 164

Code to Run

(wild code)

4 of 164

Code to Run

(wild code)

Code we write

Code we import

5 of 164

Code to Run

(wild code)

Code we write

Code we import

$$

6 of 164

Code to Teach

7 of 164

Code to Teach

Tutorials

8 of 164

Code to Teach

Tutorials

Documentation

Style Guides

Stack Overflow

Books

Conferences

9 of 164

Code to Teach

Tutorials

Documentation

Style Guides

Stack Overflow

Books

Conferences

Good Stuff

10 of 164

Syntax

SELECT ID, NAME, AGE, AMOUNT

FROM CUSTOMERS, ORDERS

WHERE CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

11 of 164

Unreadable

12 of 164

Pattern

13 of 164

Complexity

14 of 164

What we expect

15 of 164

What we get

16 of 164

Code to Teach

Code to Run

17 of 164

Code to Teach

Code to Run

18 of 164

Simple

Complex

19 of 164

Complex

Simple

20 of 164

Joe Morgan

21 of 164

Lawrence, KS

22 of 164

23 of 164

I Write Code

24 of 164

Joe Morgan

25 of 164

Joe Morgan

Read

26 of 164

Joe Morgan

Read

Read

Critically

27 of 164

Reading Code

28 of 164

Redux

29 of 164

{

donuts: [

“chocolate”,

],

filter: null

}

state.donuts.map(donut => {

return (

<h2> {{donut}} </h2>

)

})

<h2> Chocolate </h2>

State

Component

30 of 164

{

donuts: [

“chocolate”,

],

filter: null

}

state.donuts.map(donut => {

return (

<h2> {{donut}} </h2>

)

})

<h2> Chocolate </h2>

State

Component

dispatch(addDonut(‘maple’))

31 of 164

{

donuts: [

“chocolate”,

“maple”,

],

filter: null

}

state.donuts.map(donut => {

return (

<h2> {{donut}} </h2>

)

})

<h2> Chocolate </h2>

State

Component

dispatch(addDonut(‘maple’))

32 of 164

updated state

{

donuts: [

“chocolate”,

“maple”,

],

filter: null

}

state.donuts.map(donut => {

return (

<h2> {{donut}} </h2>

)

})

<h2> Chocolate </h2>

State

Component

dispatch(addDonut(‘maple’))

33 of 164

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 of 164

Redux

Functional

Array Methods

High Order Functions

Curry/Partially Applied Functions

35 of 164

Redux

36 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

chain = middlewares.map(middleware => middleware(middlewareAPI))

43 of 164

chain = middlewares.map(middleware => middleware(middlewareAPI))

chain = middlewares.map((middleware) => {return middleware(middlewareAPI)})

44 of 164

var that = this;

45 of 164

var namer = {

name: 'bill',

say: function() {

var that = this

console.log(this.name);

setTimeout(function() {

console.log(that.name);

},200);

}

}

46 of 164

var that = this;

47 of 164

const namer = {

name: 'bill',

say: function() {

console.log(this.name);

setTimeout(() => {

console.log(this.name);

},200);

}

}

48 of 164

Favor Arrow Functions

49 of 164

Why Read Wild Code?

50 of 164

i. Reading Code is a Skill

51 of 164

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 of 164

i. Reading Code is a Skill: Intuition

53 of 164

i. Reading Code is a Skill: Intuition

54 of 164

i. Reading Code is a Skill: Intuition

55 of 164

Redux

Rest/Spread

export default function applyMiddleware(...middlewares) {

// Lots of stuff

chain = middlewares.map(middleware => middleware(middlewareAPI))

dispatch = compose(...chain)(store.dispatch)

}

}

56 of 164

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)

57 of 164

Redux

Rest/Spread

Rest:

list => array

58 of 164

export default function applyMiddleware(...middlewares) {

// Lots of stuff

chain = middlewares.map(middleware => middleware(middlewareAPI))

dispatch = compose(...chain)(store.dispatch)

}

}

59 of 164

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)

60 of 164

Redux

Rest/Spread

Spread:

array => list

61 of 164

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)

62 of 164

Redux

Rest/Spread

Convert items to arrays

63 of 164

export default function applyMiddleware(...middlewares) {

// Lots of stuff

chain = middlewares.map(middleware => middleware(middlewareAPI))

dispatch = compose(...chain)(store.dispatch)

}

}

64 of 164

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 of 164

Redux

Rest/Spread

Converting array to a new array without mutations

66 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

ii. Your code will reflect your reading

83 of 164

ii. Your code will reflect your reading

data structures

architecture

community standards

84 of 164

ii. Your code will reflect your reading

It’s ok to take ideas from others

85 of 164

ii. Your code will reflect your reading

86 of 164

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 of 164

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

}

}

}

88 of 164

Redux

Object Spread

Not part of ES6

89 of 164

//.babelrc

{

"plugins": [

...

"transform-object-rest-spread",

],

...

}

90 of 164

Favor Arrow Functions

91 of 164

Favor Array Methods

(map, reduce, find, filter)

92 of 164

Collecting items to arrays

+

Arrow Functions

=

Happiness

93 of 164

Khan Academy

94 of 164

Khan Academy

Consumer code. Not a library.

95 of 164

Khan Academy

96 of 164

Khan Academy

Object Oriented

Complexity hidden behind interface

Popular in typescript (angular 2) world

97 of 164

98 of 164

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 of 164

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 of 164

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) {

...

101 of 164

iii. Feature Popularity

102 of 164

iii. Feature Popularity: Frequency

The more useful the feature the more frequent it will pop up.

103 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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

108 of 164

Khan Academy

109 of 164

export default class Expression extends Node {

get last() {

return this.children.last;

}

set last(value) {

this.children.last = value;

}

}

110 of 164

Get/Set treats methods like properties (popular in typescript)

111 of 164

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 of 164

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 of 164

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 of 164

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 of 164

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 of 164

export default class Expression extends Node {

get last() {

return this.children.last;

}

set last(value) {

this.children.last = value;

}

}

117 of 164

export default class Expression extends Node {

get last() {

return Object.assign(

{}, { name:'last' }, this.children.last

);

}

set last(value) {

this.children.last = value;

}

}

118 of 164

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 of 164

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 of 164

export default class Expression extends Node {

toString() {

return `${this.type}:${this.children.toString()}`;

}

}

121 of 164

export default class Expression extends Node {

toString() {

return this.type + ':' + this.children.toString();

}

}

122 of 164

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 of 164

export default class List extends Node {

...

toString() {

let first = true;

for (let node of this) {

// Do Stuff with node.id

}

}

}

124 of 164

export default class List extends Node {

...

toString() {

let first = true;

for (let node of this) {

// Do Stuff with node.id

}

}

}

125 of 164

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 of 164

const presentation = [

'ES6 Patterns in the Wild',

'Joe Morgan',

]

for(let metadata of presentation) {

console.log(metadata);

}

127 of 164

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 of 164

const presentation = {

title: 'ES6 Patterns in the Wild',

author: 'Joe Morgan',

}

for(let metadata of presentation) {

console.log(metadata);

}

129 of 164

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 of 164

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 of 164

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 of 164

iii. Feature Popularity:

Not all features end up being popular

133 of 164

iii. Feature Popularity:

Not all features end up being popular

134 of 164

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 of 164

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 of 164

const e = new Expression({id:1}, {id:2}, {id:3})

e = [{id:1}, {id:2}, {id:3}]

137 of 164

Khan Academy

Create Simple Interfaces

138 of 164

React

139 of 164

React

Performance

140 of 164

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 of 164

const presentation = {

title: 'ES6 Patterns in the Wild',

author: 'Joe Morgan',

}

> presentation.title

// 'ES6 Patterns in the Wild'

142 of 164

const presentation = {

title: 'ES6 Patterns in the Wild',

author: 'Joe Morgan',

}

> presentation.title

// 'ES6 Patterns in the Wild'

143 of 164

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 of 164

const presentation = new Map()

.set('title', 'ES6 Patterns in the Wild')

.set('author', 'Joe Morgan');

> presentation.get('title');

// 'ES6 Patterns in the Wild'

145 of 164

const presentation = new Map([

['title', 'ES6 Patterns in the Wild'],

['author', 'Joe Morgan']

]);

> presentation.get('title');

// 'ES6 Patterns in the Wild'

146 of 164

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 of 164

React

148 of 164

React

149 of 164

React

As ES6 becomes native there are advantages beyond style

150 of 164

Build a Library of Readable Code

151 of 164

Lurk Around Github

152 of 164

Lurk Around Github

Advanced Search

153 of 164

Glance at your dependencies

154 of 164

Have a few authors you like

155 of 164

iv. Code can be beautiful

156 of 164

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 of 164

var data = [1,2,3,4];

var updated = [];

for(var i = 0; i < data.length; i++) {

updated.push(i*i);

}

return updated;

158 of 164

const data = [1,2,3,4];

return data.map(n => n*n);

159 of 164

Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away

160 of 164

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;

161 of 164

Joe Morgan

162 of 164

Joe Morgan

@joesmorgan

163 of 164

Joe Morgan

@joesmorgan

thejoemorgan.com

164 of 164

Joe Morgan

@joesmorgan

thejoemorgan.com

https://github.com/jsmapr1