DevLeague Coding Bootcamp
DevLeague is a Full Stack Coding Bootcamp
Prototypal Inheritance and the Chain Gang
A language supports first class functions if:
//this is an object
const myObject = {};
//you can add properties(values) and methods(functions) to an object
myObject.name = 'Sam Object';
myObject.whatIsMyName = function() {
return this.name;
}
//That's it.
What's wrong with this Object?
I can't reuse it or make multiple copies of it.
(without call, apply, bind)
http://stackoverflow.com/questions/17525450/object-vs-class-vs-function
function Song() {} //just a function
Song.prototype.play = function() {
return 'playing';
}
const song = Song(); //not invoked as a constructor...no prototype
console.log(song); // undefined
const realSong = new Song(); //invoked as constructor, returns reference to new Object(function)
console.log(realSong); // Object with play method available
console.log(realSong.prototype); //has no prototype, it was CREATED using Song's prototype
Using (or not) new with function invocation
function Song() {} //just a function, nothing done in constructor(call, this.*)
Song.prototype.play = function() {
return 'playing';
}
const song = new Song(); //invoked as constructor, returns reference to new Object(function)
console.log(song); // Object with play method available
const song2 = new Song();
console.log(song2); // Object with play method available
Song.prototype.stop = function() {
return 'stopped';
}
console.log(song, song2); //both objects now have a stop method available
Adding a function to a prototype after instance creation
Applies to all instances already created
//Constructor logic to set object properties, NOT prototype properties
function Song(){
this.play = function() {
return 'Hi-jacked';
}
}
Song.prototype.play = function() {
return 'playing';
}
const song = new Song(); //invoked as constructor
console.log(song.play()); // 'Hi-jacked'
//Instance method takes precedence since constructor gets called AFTER prototype
Constructor properties take precedence in order of execution.
Create instance of object:
//Constructor logic to set object properties, NOT prototype properties
function Song() {
this.play = function() {
throw new Error('Not implemented. Need to inherit into genre.');
}
}
Song.prototype.play = function() {
return 'playing';
}
function MetalSong() {
this.volume = 11;
}
MetalSong.prototype = Object.create(Song.prototype);
const reignInBlood = new MetalSong();
reignInBlood.play(); // 'playing'
Why would we do that??
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, context) {
for (var i = 0; i < this.length; i++) {
callback.call(context || null, this[i], i, this);
}
};
}
Prototypes have a "chain" all the way up to Object
When a function is called on an instance of an object:
This is why ALL functions have toString(), call(), apply(), bind() methods.
//Constructor logic to set object properties, NOT prototype properties
function Song() {
this.play = function() {
throw new Error('Not implemented. Need to inherit into genre.');
}
}
Song.prototype.play = function() {
return 'playing';
}
function MetalSong() {
this.volume = 11;
}
MetalSong.prototype = Object.create(Song.prototype); //prototype is an object
function DeathMetalSong() {
this.volume = Infinity.max;
}
DeathMetalSong.prototype = Object.create(MetalSong.prototype);
const burningRottenLambs = new DeathMetalSong();
burningRottenLambs.play(); // 'playing'
Prototypes have a "chain" all the way up to Object
//Constructor logic to set object properties, NOT prototype properties
function Song() {
this.play = function() {
throw new Error('Not implemented. Need to inherit into genre.');
}
}
Song.prototype.play = function() {
return 'playing';
}
function MetalSong() {}
MetalSong.prototype = Object.create(Song.prototype); //prototype is an object
function DeathMetalSong() {}
DeathMetalSong.prototype = Object.create(MetalSong.prototype);
function climbTheRopes(obj){
console.log(`play() is mine: ${obj.hasOwnProperty('play')}`);
console.log(`Prototype is: ${Object.getPrototypeOf(obj)}`);
// this is the only time you would EVER need/use proto
// console.log(obj.__proto__);
if (!Object.getPrototypeOf(obj)) {
return;
}
climbTheRopes(Object.getPrototypeOf(obj));
}
const deadSilence = new DeathMetalSong();
climbTheRopes(deadSilence);
function User(first, last) {
if (!(this instanceof arguments.callee)) {
return new User(first,last);
}
this.name = first + " " + last;
}
By DevLeague Coding Bootcamp