I’ve recently been learning javascript by writing some gnome shell extensions, and hence my understanding of Javascript has been shaped by the examples I’ve observed in the gnome-shell javascript sources. I have a feeling I’ve been understanding classes wrong and just want some clarification.
I’ve written a few of my own subclasses, and in each case I’ve defined them simply by following similar code in the gnome-shell javascript source:
Subclass = function() {
this._init.apply(this,arguments);
}
Subclass.prototype = {
__proto__: Superclass.prototype,
_init: function() {
Superclass.prototype._init.call(this);
},
// add other methods of Subclass here.
}
Up to now I thought this was the standard way of making a class Subclass that was basically Superclass plus extras. I assumed that every object had a _init method.
I’ve recently tried to apply the same method to make a subclass of a Clutter.Actor (what’s important is that it’s not a GNOME-shell-defined class), and realised that the above way of subclassing objects is not the standard. For one, not every class has a _init function as I assumed; this is just something that GNOME-shell has done in their javascript classes.
So, my questions are:
- Is there any documentation regarding the above method of creating subclasses? All the tutorials I’ve seen say to set
Subclass.prototype = new Superclass()instead of doing theSubclass.prototype = { __proto__:Superclass.prototype, define_prototype_methods_here }method, but my thought is that there must be some method to it if gnome-shell uses it consistently? - If I wanted to stay as close as possible to the above way of defining classes (just so I can retain some code similarity to GNOME-shell for which I am writing extensions), what do I replace
Superclass.prototype._init.call(this)with inSubclass._initto make sure that theSubclass.prototypegets all the methods/properties ofSuperclass(which I then add on to in my definition ofSubclass.prototype), if theSuperclassdoesn’t have an_initfunction (i.e. does it have some equivalent constructor function I call)?
I’m really confused about this all so please forgive me if my question doesn’t make much sense; it’ll be because of the extent of my misunderstanding & confusion!
EDIT: clarification:
– I know the __proto__ is not recommended because it is non-standard, but my code is never going to run in a browser – it’s only ever going to run with GNOME javascript (which is basically the Mozilla javascript engine), so I don’t need to worry about cross-compatibility.
As already said, don’t use
__proto__.It’s a non-standard property.(It’s standardized for JavaScript in browsers now. Still don’t use it.) Butis not a very good method either. What if
Superclassexpects parameters?You have better options.
ES2015 and above
classhandles all of this plumbing for you; complete example:ES5 and earlier
Let
Subclass.prototypeinherit fromSuperclass.prototypeonly. This can be done for example with ES5’sObject.create:And then in
Subclass, you callSuperclasswiththisreferring to the object so it has a chance to initialize:Full example:
ES3 and earlier
ES3 and earlier don’t have
Object.create, but you can easily write a function that sets up the prototype for you in much the same way:(Note: You could half-shim
Object.createby creating one that takes only one argument, but the multiple-argument version ofObject.createcannot be shimmed, so it would be giving other code on the page the wrong idea if it also usesObject.create.)Then you do the same thing as our ES5 example:
Full example: