2017-04-26
pojo
{
year: 1981,
make: "Toyota",
model: "Tercel",
description: "Red with white fenders"
}
const myFirstCar = {
year: 1981,
make: "Toyota",
model: "Tercel",
description: "Red with white fenders"
};
🙈 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;
}
}
but the ability to create objects literally anywhere without first having to define a class is fundamentally different
literally more object oriented?
vs "class" oriented?
{
year: 1981,
make: "Toyota",
model: "Tercel",
description: "Red with white fenders"
}
function Car(year, make, model, description) {
this.year = year;
this.make = make;
this.model = model;
this.description = description;
}
const myFirstCar = new Car(
1981,
"Toyota",
"Tercel",
"Red with white fenders"
);
const mySecondCar = new Car(
1991,
"Nissan"
"Sentra"
);
constructor function
class Car {
constructor(year, make, model, description) {
this.year = year;
this.make = make;
this.model = model;
this.description = description;
}
}
const myFirstCar = new Car(
1981,
"Toyota",
"Tercel",
"Red with white fenders"
);
const mySecondCar = new Car(
1991,
"Nissan"
"Sentra"
);
"class"
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 });
const myFirstCar = createCar(
1981,
"Toyota",
"Tercel",
"Red with white fenders"
);
const mySecondCar = createCar(
1991,
"Nissan"
"Sentra"
);
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"
a way to combine simple objects or data types into more complex ones.
- wikipedia
const turtle = {animal: "turtle"};
{
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
classeswhich offer functionality that can be easily inherited by a sub-classor group of sub-classesfor the purpose of function re-use.
- Addy
emphasis mine
factory composition
- me
const createTheNextTMNT = () => ({
...createRandomAgeBracket(),
...createRandomGeneticAlteration(),
...createRandomProfession(),
...createRandomAnimal()
});
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
};
const makeBetterThanBefore = (obj) =>
({ ...obj, bacon: true });
⚠️ opinion alert
when possible
⚠️ opinion alert
when composition not feasible
why?
many reasons that all basically boil down to:
class Button extends React.Component {}
class Widget extends HTMLElement {}
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
const createSecretContainer = (secret) => () => secret;
outer fn
const mySecretContainer = createSecretContainer(
"my password is 1234"
);
inner fn
const counter = (number=0) => ({
inc: () => ++number,
dec: () => --number,
val: () => number
});
Immediately Invoked Function Expression: a JavaScript function that runs as soon as it is defined
- MDN
aka privacy
(() => {
var n = 1;
console.log(n);
})();
console.log(typeof n);
{
const n = 1;
console.log(n);
}
console.log(typeof n);
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];
}
}
})();
Game.p1Scored(2);
Game.p2Scored(3);
Game.p1Scored(2);
Game.tally();
Game.reset();
instead: cjs 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];
}
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
a convenient higher-level interface to a larger body of code, hiding its true underlying complexity
- Addy
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
why are you looping?