Last active
September 3, 2015 02:00
-
-
Save etsuo/364813d8449fd7e6ebe1 to your computer and use it in GitHub Desktop.
Javascript Prototype Notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
// essentially a parent "class" - these are not abstract entities | |
// per se that can be instantiated. However, when you call | |
// new Foo('some value'); then Foo is executed and what's returned | |
// is a new object with a copy of the values from Foo -- this | |
// points to the new copy of Foo... | |
function Foo(name) { | |
this.name = (name === undefined) ? 'Name was not set' : name; | |
} | |
// Associate a reference to a new function called myName() with Foo() | |
Foo.prototype.myName = function() { | |
return this.name; | |
}; | |
// test the parent object | |
var a = new Foo('J.P.'); | |
console.log('Foo'); | |
console.log(a.myName()); | |
/********************************************************************/ | |
// essentially a child "class" | |
// note: Foo.call(this, name) - this causes Foo() to be executed in | |
// the context of Bar's this when new Bar(...) is called. Because | |
// Foo() is called in the context of Bar's this, Bar ends up with | |
// Foo's this.name. | |
function Bar(name, label) { | |
Foo.call(this, name); | |
this.label = label; | |
} | |
// dump Bar's default prototype chain and create a copy | |
// of Foo's to attach to bar - this is how Bar gets Foo's | |
// functions (myName()). | |
// | |
// Object.create means that Bar has Foo's prototype chain but not | |
// the other way around (see the link test below). You could use | |
// new Foo(), but that would cause a constructor call of Foo(), | |
// not something you want when you're simply wiring up the relationship | |
// off your objects. | |
Bar.prototype = Object.create ( Foo.prototype ); | |
// Associate a reference to a new function called myLabel() with Bar() | |
Bar.prototype.myLabel = function() { | |
return this.label; | |
}; | |
var b = new Bar('J.P.', 'Test Label'); | |
// You now have an object b that is a Bar which | |
// has a copy of Foo's prototype chain that Bar then | |
// attached a reference to the function myLabel. | |
// Bar has the property name and label. | |
// test the child object | |
console.log('Bar'); | |
console.log(b.name); | |
console.log(b.label); | |
console.log(b.myName()); | |
console.log(b.myLabel()); | |
// Note that Bar is linked to Foo in some mutatible ways | |
Foo.prototype.linkTest = function() { | |
console.log('Linked!'); | |
}; | |
b.linkTest(); | |
// But not the other way around | |
var c = new Foo('test'); | |
console.log((c.myLabel === undefined) ? 'not present' : 'weird, it was found'); | |
// You can test if something is the prototype of something else like this: | |
console.log('Foo is prototype of c? ' + Foo.prototype.isPrototypeOf( c )); | |
console.log('Foo is prototype of b? ' + Foo.prototype.isPrototypeOf( b )); | |
console.log('Foo is prototype of a? ' + Foo.prototype.isPrototypeOf( a )); | |
console.log('Bar is prototype of a? ' + Bar.prototype.isPrototypeOf( a )); | |
// The object.create way of doing things: | |
var foo = { | |
name: '', | |
myName: function() { | |
console.log( "My name is " + this.name ); | |
} | |
}; | |
// This approach requires ES5 | |
var bar = Object.create( foo, { | |
label: { value: '', writable: true}, | |
myLabel: { value: function() { | |
console.log('My name is ' + this.name + ' and my label is ' + this.label); | |
}} | |
}); | |
bar.name = "J.P."; | |
bar.label = "Test Label"; | |
bar.myLabel(); | |
// This approach can be polyfilled pre ES5 | |
var bar2 = Object.create( foo ); | |
bar2.name = 'J.P.'; | |
bar2.label = 'Test Label'; | |
bar2.myLabel = function() { | |
return 'My name is ' + this.name + ' and my label is ' + this.label; | |
}; | |
console.log(bar2.myLabel()); | |
var bar3 = Object.create( bar2 ); | |
bar3.color = 'blue'; | |
bar3.myLabel = function() { | |
return 'My name is ' + this.name + ' and my label is ' + this.label + ' and my color is ' + this.color; | |
}; | |
console.log(bar3.myLabel()); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment