Inheritance patterns in JavaScript
(by way of a brief history of music)
Classical
Inheritance
In JavaScript
class Blues {
constructor () {
this.genre = 'Blues'
this.dance = 'Blues Dancing'
}
get instruments() { return [
'guitar',
'trumpet',
'standup bass',
'drums'
]
}
}
var bbKing = new Blues()
bbKing.dance // 'Blues Dancing'
A Classic class
class Definition
class Blues {
constructor (...constructorArgs) {
this.someInstanceProperty = `You can't inherit me`
this.someOtherInstanceProperty = constructorArgs[0]
}
someMethodOnThePrototype() { ... }
get somePropertyOnThePrototype() {
// Access me like a class property
// ( myInstance.somePropertyOnThePrototype //-> 4 )
return 4
}
set somePropertyOnThePrototype(val) {
// Assign to me like a class property
// ( myInstance.somePropertyOnThePrototype = 4 )
this.somePropertyOnThePrototype = val
}
}
const bbKing = new Blues();
Object Instantiation
How about a new class that inherits from Blues?
A Jazzy Class
class Jazz extends Blues {
constructor () {
this.genre = 'Jazz'
this.dance = 'groove'
}
}
const milesDavis = new Jazz()
milesDavis.genre // Jazz
milesDavis.instruments // ['guitar', 'trumpet', 'standup bass', 'drums']
(pseudo)Classical Inheritance in Javascript
Boom
... but ...
This Is
Just A
Façade
Javascript
is not A Classical Language
Class are sugar around a restricted form of prototypal inheritance
Classes are objects in JavaScript. They are referenceable, and mutable.
There is (currently) no way to "declare" a private variable within the class.
Absent the `class` sugar, classes are simple functions called with the `new` keyword.
Classical Inheritance in JavaScript is Actually pseudo-Classical Inheritance
"The pesudoclassical form can provide comfort to programmers who are unfamiliar with JavaScript, but it also hides the true nature of the language."
-Douglas Crockford
Classical Inheritance in JavaScript is dumbed down prototypal inheritance
SPEAKING OF PROTOTYPAL INHERITANCE
ALL OBJECTS IN JAVSCRIPT inherit from a PROTOTYPE
THE PROTOTYPE
rock = {};
/*
{
__proto__: {...}
}
*/
ROck INHERITANCE
const rock = {
instruments: [
'electric guitar',
'bass',
'drums',
],
genre: 'Rock',
dance: 'Fist Pump'
};
const theWho = Object.create(rock);
theWho.dance = 'Jump';
const theWho = Object.create(rock);
Here we tell JavaScript to create a new object with rock as its prototype.
What it looks like
{
dance: 'Jump'
__proto__: {
instruments: [
'electric guitar',
'bass',
'drums'
],
dance: 'Fist Pump',
genre: 'Rock'
}
}
PROTOtypes are dynamic SO WE CAN ADD TO THEM
ADD SOME KEYBOARD and volume
rock.volume = 10;
rock.instruments.push('keyboard');
/*
theWho.volume // 10
theWho.instruments // [ 'electric guitar', 'bass', 'drums', 'keyboard']
*/
theWho.__proto__.volume = 11;
/*
rock.volume // 11
theWho.volume // 11
*/
Functional Composition in JavaScript
JavaScript is a Functional Language
The Humble Object
const milesDavis = {}
with properties
const milesDavis = {
genre: 'Jazz',
instruments: [
'guitar',
'trumpet',
'standup bass',
'drums'
]
}
and methods
const milesDavis = {
genre: 'Jazz',
instruments: [
'guitar',
'trumpet',
'standup bass',
'drums'
],
dance: () => 'Groove'
}
Cool!
Let's make something that Does stuff to it.
bigbandinator Function
const bigBandinator = ({ instruments = [], ...objectIn }) => ({
...objectIn,
instruments: [...new Set([
'drums',
'trumpets',
'trombones',
'saxophones',
'standup bass',
...instruments || []
])],
dance: 'Charleston',
genre: 'Big Band'
})
bigbandinate Mr Davis
const glenMillerOrchestra = bigBandinator(milesDavis)
/*
{
genre: 'Big Band',
dance: 'Charleston',
instruments: [
'drums',
'trumpets',
'trombones',
'saxophones',
'standup bass'
]
}
*/
We have achieved functional inheritance
Cool!
But what if we "inated" multiple Objects?
bigband
+ Punk
How about a Punk ojbect?
const ramones = {
genre: 'Punk',
dance: 'mosh',
instruments: [
'drums',
'electric guitar',
'bass'
]
}
We need a punkinator
Let's Make it an Inator
const punkinator = ({ instruments=[], ...objectIn }) => ({
...objectIn,
instruments: [...new Set([
'drums',
'electric guitar',
'bass',
...instruments
])],
dance: 'Mosh',
genre: 'Punk'
})
Behold, the birth of SKA!
const skainator = (objectIn) => ({
...bigBandinator(objectIn),
...punkinator(objectIn),
genre: 'Ska',
dance: 'Skank'
})
The Ska Robot Army
const aquaBats = {
members: {
"Christian Jacobs": "MC Bat Commander",
"Matt Von Gundy": "Gumby",
"Ben Bergeson": "Ben the Brain",
"Charles Gray": "Mysterious Kyu",
"Chad Larson": "Crash McLarson",
"Chad Parkin": "Nacho",
"Rod Arellano": "Roddy B.",
"Boyd Terry": "Catboy",
"Adam Deibert": "Prince Adam",
}
}
skainator(aquaBats)
The Fury of the Aquabats
{
members: {
"Christian Jacobs": "MC Bat Commander",
"Matt Von Gundy": "Gumby",
"Ben Bergeson": "Ben the Brain",
"Charles Gray": "Mysterious Kyu",
"Chad Larson": "Crash McLarson",
"Chad Parkin": "Nacho",
"Rod Arellano": "Roddy B.",
"Boyd Terry": "Catboy",
"Adam Deibert": "Prince Adam",
},
instruments: [
'drums',
'electric guitar',
'bass'
'trumpets',
'trombones',
'saxophones',
'standup bass'],
genre: 'ska',
dance: 'skank'
}
You have been inated
Classical Inheritance
By Cory Brown
Classical Inheritance
- 2,300