Class.prototype.method vs this.prototype.method
I’ve always seen examples of Class.prototype.method, but never instances of this.prototype.method. For example:
function Class() {
this.prototype.method = function() {
alert("is this allowed?");
};
}
vs
function Class() {}
Class.prototype.method = function() {
alert("traditional example");
};
- Does this.prototype exist?
- Is it the same as Class.prototype?
- What about inheritance?
-
Does this.prototype exist?
No. But,
this.constructor.prototype
should. -
Is it the same as Class(.constructor).prototype?
It will generally have the same value (so long as
this.constructor === Class
), but not the same intent. -
What about inheritance?
Each
new Class
instance will inherit fromClass.prototype
. So, aprototype
object is good for defining shared values accessible to all instances. Then, the constructor just has to setup state that’s unique to each instance.But, attempting to mix the 2 and set a
prototype
property within the constructor has a few problems, including a chicken-or-egg conflict as the method won’t exist until the first instance is created:function Class() { this.constructor.prototype.method = function () {}; } console.log(typeof Class.prototype.method); // "undefined" var a = new Class(); console.log(typeof Class.prototype.method); // "function"
And defeats some of the benefit of having the
prototype
as the method is being recreated with each additional instance:var method = a.method; console.log(a.method === method); // true var b = new Class(); console.log(a.method === method); // false
this.prototype would refer to that instance of the class object. It wouldn’t give you much benefit because of the scope.
Class.prototype is adding functionality to the Class, not the instance of it.
Class
is a function; this
is an object. Functions have a prototype
property; objects do not. There’s a __proto__
property defined on objects, but that interface is deprecated. You can do something like
function Class () {
var prototype = Object.getPrototypeOf(this);
prototype.method = function () {};
}
inside your constructor but it’s not really good practice – every time Class
is instantiated, it will needlessly waste cycles overwriting method
on the prototype, and in cases with more complex code, may end up wasting memory as well.
In short, there’s no upside and possibly serious downsides to doing it that way.
You can achieve the same effect in two different ways. But in both, you must first instantiate Class.
First way
function Class () {
var prototype = Object.getPrototypeOf(this);
prototype.foo=100
}
new Class()
console.log(Object.getOwnPropertyNames(Class.prototype))
And second
function Class () {
//var prototype = Object.getPrototypeOf(this);
var prototype=this.constructor.prototype
prototype.foo=100
}
new Class()
console.log(Object.getOwnPropertyNames(Class.prototype))
Both give output
["constructor", "foo"]
The only difference is that instead of doing this.constructor.prototype
you can get it returned from Object.getPrototypeOf(this)
. Both returns the prototype of an instance of Class.