You can see this pattern in a number of libraries
EDIT
You can see this pattern in a number of libraries
EDIT
EDIT
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
foo.hello = function(){ return "こんにちは"; };
// call our hello method again
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello = function(){ return "こんにちは"; };
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
PROTOTYPESThis would work too, but I never really have the need. I suppose the benefit is you don't need to know the original class this way :)
// call original method from the instance
foo.__proto__.hello.call(foo); //=> "hello!"
PROTOTYPES!
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello = function(){ return "こんにちは"; };
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
PROTOTYPES :)
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
foo.hello = function(){ return "こんにちは"; };
// call our hello method again
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
This would work too, but I never really have the need. I suppose the benefit is you don't need to know the original class this way :)
// call original method from the instance
foo.__proto__.hello.call(foo); //=> "hello!"
PROTOTYPES!
var Foo = function(){};
Foo.prototype.hello = function(){ console.log(return "hello!");"; };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello = function(){ console.log("こんにちは");return "こんにちは"; };
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
As you can see, you lose this functionality by directly defining methods on the instance using this.something = function(){};. I personally prefer defining methods on the prototype because of the added flexibility. This way, the prototype really works like a blueprint. You get all the pre-defined behavior; you can modify if necessary and revert to the original whenever you want, all on a per-instance basis.
ONE MORE THING
In our last example, we had a prototype method and an instance method override. Is there a way to call the original method too? Let's see!
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
foo.hello = function(){ return "こんにちは!"; }
// call override method
foo.hello(); //=> "こんにちは!"
// call original method
Foo.prototype.hello.call(foo); //=> "hello!"
// japanese just one more time...
foo.hello(); //=> "こんにちは!"
PROTOTYPES :)
var Foo = function(){};
Foo.prototype.hello = function(){ console.log("hello!"); };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
// this calls foo.hello because it is defined directly on our instance
foo.hello = function(){ console.log("こんにちは"); };
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
As you can see, you lose this functionality by directly defining methods on the instance using this.something = function(){};. I personally prefer defining methods on the prototype because of the added flexibility. This way, the prototype really works like a blueprint. You get all the pre-defined behavior; you can modify if necessary and revert to the original whenever you want, all on a per-instance basis.
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"
// override `hello` method for this instance
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello = function(){ return "こんにちは"; };
foo.hello(); //=> "こんにちは"
// remove the override
delete foo.hello;
// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"
// remove the method prototype
delete Foo.prototype.hello
// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'
As you can see, you lose this functionality by directly defining methods on the instance using this.something = function(){};. I personally prefer defining methods on the prototype because of the added flexibility. This way, the prototype really works like a blueprint. You get all the pre-defined behavior; you can modify if necessary and revert to the original whenever you want, all on a per-instance basis.
ONE MORE THING
In our last example, we had a prototype method and an instance method override. Is there a way to call the original method too? Let's see!
var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();
foo.hello = function(){ return "こんにちは!"; }
// call override method
foo.hello(); //=> "こんにちは!"
// call original method
Foo.prototype.hello.call(foo); //=> "hello!"
// japanese just one more time...
foo.hello(); //=> "こんにちは!"
PROTOTYPES :)