Last active
September 25, 2015 22:30
-
-
Save zwhitchcox/420e72aa9433ba1ab40d to your computer and use it in GitHub Desktop.
Classic inheritance function in javascript
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
// **IMPORTANT** Not compatible with <= IE10 (which makes up about 20% of browsers) | |
// Here ya go! Just put this in your global scope: | |
// Works fine with all real browsers though | |
function inherit(inhObj,self) { | |
var selfProto = Object.getPrototypeOf(self) | |
var inheritance=Object.create(inhObj.prototype); | |
for (var i in selfProto) {inheritance[i] = selfProto[i]}; | |
if (Object.setPrototypeOf) | |
Object.setPrototypeOf(self,inheritance); | |
else | |
self.__proto__ = inheritance | |
inhObj.call(self); | |
} | |
// Then just say `inherit(inheritanceObj,this)` | |
// at the top of the function you want to inherit from. For instance: | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round' | |
} | |
Fruit.prototype.getTaste = function() { | |
console.log(this.taste) | |
} | |
var Apple = function() { | |
inherit(Fruit,this); | |
this.taste = 'sweet' | |
} | |
var apple= new Apple() | |
apple.taste // "sweet" | |
apple.getTaste() // sweet | |
function Pineapple() { | |
inherit(Fruit,this); | |
this.shape = 'ovular'; | |
} | |
var pineapple = new Pineapple() | |
pineapple.taste // 'good' | |
pineapple.shape // 'ovular' | |
// Most people say to do something like this: | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round'; | |
} | |
Fruit.prototype.getTaste = function() { | |
console.log(this.taste) | |
} | |
var Apple = function() { | |
Fruit.call(this); | |
this.taste = 'sweet' | |
} | |
var Pineapple = function() { | |
Fruit.call(this); | |
this.shape = 'ovular' | |
} | |
Apple.prototype = Object.create(Fruit.prototype) | |
Pineapple.prototype = Object.create(Fruit.prototype) | |
var apple = new Apple() | |
var pineapple = new Pineapple() | |
apple.taste // 'sweet' | |
apple.getTaste() // sweet | |
pineapple.shape // 'ovular' | |
pineapple.taste // 'good' | |
// And that works, but it kind of clutters up your code, and you have | |
// to make sure you declare Apple's prototype functions *after* you | |
// have set the prototype to inherit. This can be kind of tricky, | |
// especially if your planning on inheriting from different files and | |
// stuff, but whatever floats your boat! | |
// It's also kind of confusing for someone who doesn't know you're | |
// inheriting something. Sure my code's more confusing, but it's really | |
// none of their concern, as it's abstracted. The conventional method looks | |
// like it's doing something important, and this is really a hack for | |
// something JavaScript didn't expect you to do anyway. | |
// Note: If you change/add a prototypal function later on to an | |
// inherited object, it will be propagated to the its inheritors. i.e. | |
Apple.prototype.sayhi = function() {console.log('hi')} | |
apple.sayhi() // 'hi' |
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
// both ways are roughly the same in terms of efficiency | |
// even when used within angular | |
function inherit(inhObj,self) { | |
var selfProto = Object.getPrototypeOf(self) | |
var inheritance=Object.create(inhObj.prototype); | |
for (var i in selfProto) {inheritance[i] = selfProto[i]}; | |
if (Object.setPrototypeOf) | |
Object.setPrototypeOf(self,inheritance); | |
else | |
self.__proto__ = inheritance | |
inhObj.call(self); | |
} | |
// Then just say `inherit(inheritanceObj,this)` | |
// at the top of the function you want to inherit from. For instance: | |
var start = Number(new Date().getTime()); | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round' | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
inherit(Fruit,this); | |
this.taste = 'sweet' | |
} | |
var apple= new Apple() | |
for (var i = 0; i < 1000000; i++) { | |
apple.getTaste() | |
} | |
console.log('my time: ' + (Number(new Date().getTime()) -start)) | |
start = new Date(); | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round'; | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
Fruit.call(this); | |
this.taste = 'sweet' | |
} | |
Apple.prototype = Object.create(Fruit.prototype) | |
Apple.prototype.constructor = Apple | |
var apple = new Apple() | |
for (var i = 0; i < 1000000; i++) { | |
apple.getTaste() | |
} | |
console.log('their time: ' + (Number(new Date().getTime()) -start)) | |
// 2nd test | |
// here we create 1000 objects, iterating through each 1000 | |
// results are about the same. | |
var mine = theirs = 0; | |
for(var j = 0; j < 1000; j++) { | |
// Then just say `inherit(inheritanceObj,this)` | |
// at the top of the function you want to inherit from. For instance: | |
var start = Number(new Date().getTime()); | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round' | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
inherit(Fruit,this); | |
this.taste = 'sweet' | |
} | |
var apple= new Apple() | |
for (var i = 0; i < 1000; i++) { | |
apple.getTaste() | |
} | |
mine+= Number(new Date().getTime()) -start | |
start = new Date(); | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round'; | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
Fruit.call(this); | |
this.taste = 'sweet' | |
} | |
Apple.prototype = Object.create(Fruit.prototype) | |
Apple.prototype.constructor = Apple | |
var apple = new Apple() | |
for (var i = 0; i < 1000; i++) { | |
apple.getTaste() | |
} | |
theirs += Number(new Date().getTime()) -start | |
} | |
console.log('theirs: '+theirs+' ' + 'mine: '+mine) | |
// 3rd test | |
// create 1,000,000 objects | |
var start = Number(new Date().getTime()); | |
for(var j = 0; j < 100000; j++) { | |
// Then just say `inherit(inheritanceObj,this)` | |
// at the top of the function you want to inherit from. For instance: | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round' | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
inherit(Fruit,this); | |
this.taste = 'sweet' | |
} | |
var apple= new Apple() | |
} | |
console.log('mine: '+ (Number(new Date().getTime()) -start)) | |
var start = Number(new Date().getTime()); | |
for (var j = 0; j<100000; j++) { | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round'; | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
Fruit.call(this); | |
this.taste = 'sweet' | |
} | |
Apple.prototype = Object.create(Fruit.prototype) | |
var apple = new Apple() | |
} | |
console.log('theirs: '+ (Number(new Date().getTime()) -start)) | |
// 3rd test | |
// create 1,000,000 objects | |
// results when creating a million objects...not so good | |
// The accepted way is about 50% faster | |
// this is creating 1,000,000 objects though. neither way is particularly | |
// fast. Both tests take over 20 seconds. If you're going to be | |
// creating over 100,000 objects in your code for whatever reason | |
// you should probably use something different | |
var start = Number(new Date().getTime()); | |
for(var j = 0; j < 10000000; j++) { | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round' | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
inherit(Fruit,this); | |
this.taste = 'sweet' | |
} | |
var apple= new Apple() | |
} | |
console.log('mine: '+ (Number(new Date().getTime()) -start)) | |
var start = Number(new Date().getTime()); | |
for (var j = 0; j<10000000; j++) { | |
var Fruit = function() { | |
this.taste = 'good'; | |
this.shape = 'round'; | |
} | |
Fruit.prototype.getTaste = function() { | |
this.taste+='d' | |
} | |
var Apple = function() { | |
Fruit.call(this); | |
this.taste = 'sweet' | |
} | |
Apple.prototype = Object.create(Fruit.prototype) | |
var apple = new Apple() | |
} | |
console.log('theirs: '+ (Number(new Date().getTime()) -start)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment