Skip to content

Instantly share code, notes, and snippets.

@zwhitchcox
Last active September 25, 2015 22:30
Show Gist options
  • Save zwhitchcox/420e72aa9433ba1ab40d to your computer and use it in GitHub Desktop.
Save zwhitchcox/420e72aa9433ba1ab40d to your computer and use it in GitHub Desktop.
Classic inheritance function in javascript
// **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'
// 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