Skip to content

Instantly share code, notes, and snippets.

@ypetya
Last active August 29, 2015 14:07
Show Gist options
  • Save ypetya/3652d85f15d18a302dbf to your computer and use it in GitHub Desktop.
Save ypetya/3652d85f15d18a302dbf to your computer and use it in GitHub Desktop.
javascript prototype inheritance, apply, call, Object.create

Prototype inheritance

It can be implemented in multiple ways

  • using call and apply functions to change the scope of the this keyword
  • using the ECMA5 feature Object.create

examples for

  • apply
  • call
  • mixin
define(function(){
/**
* Emulating how Object.create works.
* Is the implementation below equivalent with Object.create?
* just a test
*/
// Constructor emulating inheritance
var Constructor = function (parameterMap, parentObject) {
for(var key in parameterMap) {
if(parameterMap.hasOwnProperty(key)) {
this[key] = parameterMap[key];
}
}
if( typeof parentObject !== 'undefined' ) {
this.prototype = parentObject;
for(var fn in parentObject) {
if(!this.hasOwnProperty(fn)) {
this[fn] = parentObject[fn];
}
}
}
}
var testParent = new Constructor( {
'name' : 'parent',
'parentProperty' : 'test',
'parentFn' : function () { console.log('parent fn'); }
});
describe('The factory (the Constructor)', function() {
it('can create an object', function() {
expect(testParent).toBeDefined();
});
it('can set up the properties', function() {
expect(testParent.name).toEqual('parent');
expect(testParent.parentProperty).toEqual('test');
expect(testParent.parentFn).toBeDefined();
});
it('can create an object without a parent object', function() {
expect(testParent.prototype).toBeUndefined();
});
});
describe('An instance of a parent created by the constructor', function() {
var testInstance = new Constructor({ 'name' : 'child1'}, testParent);
it('has a prototype', function() {
expect(testInstance.prototype).toBeDefined();
});
it('has the prototype same as the parent', function() {
expect(testInstance.prototype).toEqual(testParent);
});
it('can have its own properties', function() {
expect(testInstance.name).toBeDefined();
});
it('has the parents functions', function() {
expect(testInstance.parentFn).toBeDefined();
});
it('has the parents properties', function() {
expect(testInstance.parentProperty).toBeDefined();
});
});
describe('An instance of a parent created by Object.create', function() {
var testInstance = Object.create(testParent);
it('has the parents properties', function() {
expect(testInstance.parentProperty).toBeDefined();
});
it('has the parents functions', function() {
expect(testInstance.parentFn).toBeDefined();
});
});
})
var originalfoo = someobject.foo;
someobject.foo = function() {
// Do stuff before calling function
console.log(arguments);
// Call the function as it would have been called normally:
originalfoo.apply(this, arguments);
// Run stuff after, here.
}
function Animal(name) {
// Instance properties can be set on each instance of the class
this.name = name;
}
// Prototype properties are shared across all instances of the class. However, they can still be overwritten on a per-instance basis with the `this` keyword.
Animal.prototype.speak = function() {
console.log("My name is " + this.name);
};
var animal = new Animal('Monty');
animal.speak(); // My name is Monty
// cat inherited from animal
var cat = Object.create(Animal);
cat.speak();
function Animal(name) {
// Instance properties can be set on each instance of the class
this.name = name;
}
// Prototype properties are shared across all instances of the class. However, they can still be overwritten on a per-instance basis with the `this` keyword.
Animal.prototype.speak = function() {
console.log("My name is " + this.name);
};
var animal = new Animal('Monty');
animal.speak(); // My name is Monty
// cat inherited from animal
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype = new Animal();
var cat = new Cat('Monty');
cat.speak(); // My name is Monty
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment