javascript
patterns

2017-04-26

literals

pojo

{
    year: 1981,
    make: "Toyota",
    model: "Tercel",
    description: "Red with white fenders"
}

to create an object shaped like

const myFirstCar = {
    year: 1981,
    make: "Toyota",
    model: "Tercel",
    description: "Red with white fenders"
};

we literally just: 

what about methods?

🙈 if you're into that sort of thing

const myFirstCar = {
    year: 1981,
    make: "Toyota",
    model: "Tercel",
    description: "Red with white fenders",
    tryToStart() {
        return Math.random() < .3;
    }
}

"methods"

this might seem basic

but the ability to create objects literally anywhere without first having to define a class is fundamentally different

🤔

JavaScript

literally more object oriented?

🤔

vs "class" oriented?

factories

{
    year: 1981,
    make: "Toyota",
    model: "Tercel",
    description: "Red with white fenders"
}

to create a bunch of objects shaped like

function Car(year, make, model, description) {
    this.year = year;
    this.make = make;
    this.model = model;
    this.description = description;
}

we can

const myFirstCar = new Car(
    1981,
    "Toyota",
    "Tercel",
    "Red with white fenders"
);

const mySecondCar = new Car(
    1991,
    "Nissan"
    "Sentra"
);

and then

constructor function

or

class Car {
    constructor(year, make, model, description) {
        this.year = year;
        this.make = make;
        this.model = model;
        this.description = description;
    }
}

we can

const myFirstCar = new Car(
    1981,
    "Toyota",
    "Tercel",
    "Red with white fenders"
);

const mySecondCar = new Car(
    1991,
    "Nissan"
    "Sentra"
);

and then

"class"

or

In JavaScript, we can literally create a new object anywhere.

- literally a few slides ago

In JavaScript, any function can return a new object.  When it’s not a constructor function or class, it’s called a factory function

 

- someone on the internet

const createCar = (year, make, model, description) =>
    ({ year, make, model, description });

factory

const myFirstCar = createCar(
    1981,
    "Toyota",
    "Tercel",
    "Red with white fenders"
);

const mySecondCar = createCar(
    1991,
    "Nissan"
    "Sentra"
);

and then

class Car {
    constructor(year, make, model, description) {
        this.year = year;
        this.make = make;
        this.model = model;
        this.description = description;
    }
}

"class"

function Car(year, make, model, description) {
    this.year = year;
    this.make = make;
    this.model = model;
    this.description = description;
}

constructor function

const createCar = (year, make, model, description) =>
    ({ year, make, model, description });

"factory"

compare

object composition

a way to combine simple objects or data types into more complex ones.

- wikipedia

const turtle = {animal: "turtle"};

eg: take objects shaped like

and create a new object that looks like

{
    age: 16,
    isMutant: true,
    job: "ninja",
    animal: "turtle"
}
const mutant = {isMutant: true};
const ninja = {job: "ninja"};
const teenage = {age: 16};

...

const tmnt = {
    ...teenage,
    ...mutant,
    ...ninja,
    ...turtle
};

💥

const tmnt = Object.assign(
    {},
    teenage,
    mutant,
    ninja,
    turtle
);

☝️ Everything but IE (MS Edge+)

and easy to polyfill

mixins

classes which offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of function re-use.

- Addy

emphasis mine

factory composition

- me

const createTheNextTMNT = () => ({
    ...createRandomAgeBracket(),
    ...createRandomGeneticAlteration(),
    ...createRandomProfession(),
    ...createRandomAnimal()
});

hollywood idea generator

decorators

allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class

- wikipedia

emphasis mine

append data or behavior to an object

- JAT

const betterThanBefore = {
    ...obj,
    bacon: true
};

one-off decoration

const makeBetterThanBefore = (obj) =>
    ({ ...obj, bacon: true });

decoration factory

inheritance

⚠️ opinions

prefer composition over inheritance

⚠️ opinion alert

when possible

prefer shallow inheritance

⚠️ opinion alert

when composition not feasible

velocity

why?
many reasons that all basically boil down to:

🏃💨

class Button extends React.Component {}

class Widget extends HTMLElement {}

"classes" aka prototypes

closures

Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.

- MDN

closures
NEVER FORGET

🇺🇸

currying exemplifies a closure
👇

const createSecretContainer = (secret) => () => secret;
  • a function which accepts an argument and creates & returns a function
  • the created "inner" function has access to the "outer" function's scope 

outer fn

const mySecretContainer = createSecretContainer(
    "my password is 1234"
);
  • `mySecretContainer` is the returned, inner function
  • `mySecretContainer` still "remembers" the `secret` defined in its original outer scope

inner fn

counter: a closure demo

const counter = (number=0) => ({
  inc: () => ++number,
  dec: () => --number,
  val: () => number
});

iife

Immediately Invoked Function Expression: a JavaScript function that runs as soon as it is defined

- MDN

useful for encapsulating scope

aka privacy

(() => {
    var n = 1;
    console.log(n);
})();

console.log(typeof n);

example

a foundational concept, but generally not authored directly nowadays

{
  const n = 1;
  console.log(n);
}

console.log(typeof n);
  • privacy via block-scoped const & let
  • privacy via modules

module pattern

encapsulating functionality using

IIFE + closure

const Game = (() => {
    let p1 = 0;
    let p2 = 0;

    return {
        p1Scored(n=0) {
            p1+=n;
        },        

        p2Scored(n=0) {
            p2+=n;
        },

        tally() {
            return [p1, p2];
        },
        
        reset() {
            p1 = p2 = 0;
            return [p1, p2];
        }
        
    }
    
})();

example

Game.p1Scored(2);
Game.p2Scored(3);
Game.p1Scored(2);
Game.tally();
Game.reset();
  • create an IIFE to encapsulate scope
  • define private variables
  • return an object containing functions which "remember" the variables `p1` and `p2` 
  • `Game` becomes the returned object

instead: cjs es6 modules 👉

another foundational concept, but generally not authored directly nowadays

es6 modules

let p1 = 0;
let p2 = 0;

export const p1Scored = (n=0) => {
    p1+=n
};

export const p2Scored = (n=0) => {
    p2+=n;
}

export const tally = () => [p1, p2];

export const reset = () => {
    p1 = p2 = 0;
    return [p1, p2];
}

example

import * as Game from './Game.js';

Game.tally();

Game.p1Scored(2);
Game.p2Scored(3);
Game.p1Scored(2);

Game.tally();
Game.reset();

Game.p1Scored(2);
import {
    tally,
    p2Scored
} from './Game.js';

p2Scored(5);
tally();
import './file1.js';
import './file2.js';

./Game.js

./app.js

./file1.js

./file2.js

es6 modules:

like importing an IIFE module

facade

 a convenient higher-level interface to a larger body of code, hiding its true underlying complexity

- Addy

modules

dude, just use

import handleComplexThingA from './a.js';
import handleComplexThingB from './b.js';
import handleComplexThingC from './c.js';

const facade = ({condition, ...data}) => {
    if(condition==="a") {
        return handleComplexThingA(data);
    }

    if(condition==="b") {
        return handleComplexThingB(data);
    }

    if(condition==="c") {
        return handleComplexThingB(data);
    }

    return null;
}

export default facade;

./index.js

looping

javascript patterns for dealing with lists of things

which loop type?

why are you looping?

async

asynchronous I/O, or non-blocking I/O is a form of input/output processing that permits other processing to continue before the transmission has finished

async patterns

  • events
  • callbacks
  • promises
  • async/await
  • observables (coming?)

end 👏

JavaScript Patterns

By Jared Anderson

JavaScript Patterns

  • 2,088