Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Revisions

6 of 8
Explain prototype in depth
Mulan
  • 136.1k
  • 35
  • 240
  • 276

For parent/child classes, I would do something like this

// your parent class
var Parent = function() {
 // parent constructor
 console.log("parent constructor!");
 
 // some public properties
 this.foo = "foo";
 this.bar = "bar";
 // a private data member
 var secret = "123456";
};
// a parent function
Parent.prototype.something = function() {
 console.log("something!");
}
// your child class
var Child = function() {
 
 // call parent constructor
 Parent.call(this); 
 
 // child constructor
 console.log("child constructor!");
 // override bar
 this.bar = "override!";
};
// the magic!
// child prototype build from parent prototype
Child.prototype = Object.create(Parent.prototype, {constructor: {value: Child}});

Example usage

var c = new Child();
c.something();
// => parent constructor!
// => child constructor!
// => something!
c.foo //=> "foo"
c.bar //=> "override!"

If you're using "namespacing" the concept is identical.


You can see this pattern in a number of libraries


EDIT

Per your comment, here's and added demonstration

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 :)

Mulan
  • 136.1k
  • 35
  • 240
  • 276

AltStyle によって変換されたページ (->オリジナル) /