Unfortunately there is a bit of mix of Class styles, for couple reasons, but namely because GJS existed before ES6 classes. You should avoid usage of the Lang
module if at all possible.
Sometimes it won't be clear if the object you're subclassing is a native JS class or a GObject. Any object coming from imports.gi
(GObject Introspection) will be a GObject, while objects coming from say imports.ui.popupMenu
(an import in GNOME Shell) could be either and you may have to check the source.
If you are subclassing a GObject, this is the proper way to subclass:
var Bin = GObject.registerClass({
// This is optional, but useful to avoid namespace collisions. By
// convention you prefix your GType's like StBin or GtkBin.
GTypeName: 'PohoBin',
// Custom GProperties
Properties: {
'example-prop': GObject.ParamSpec.string(
'example-prop', // property name
'ExampleProperty', // nickname
'An example read write property', // description
(GObject.ParamFlags.READWRITE | // READABLE/READWRITE/CONSTRUCT/etc
GObject.ParamFlags.CONSTRUCT),
null // implement defaults manually
)
}
}, class Bin extends St.Bin {
// Currently GObjects use `constructor()` for bootstrapping; you
// should not call this function in GObject subclasses.
//
// Instead, you should chain-up to the parent class's _init() function,
// which takes a dictionary of properties
_init(params = {}) {
// Chaining up. If you need to, you can use this opportunity to
// pull properties from the @params dictionary
super._init(params);
}
get example_prop() {
if (this._example_prop === undefined)
this._example_prop = null;
return this._example_prop;
}
set example_prop(value) {
if (this.example_prop !== value) {
this._example_prop = value;
this.notify('example-prop');
}
}
foo() {
log(this.example_prop);
}
});
let obj = new Bin({
visible: true, // Clutter.Actor property
x_align: St.Align.MIDDLE, // St.Bin property
example_prop: 'example' // custom property
});
obj.foo();
// expected output: 'example'
There is more information about mapping GObject to JavaScript here:
https://gitlab.gnome.org/GNOME/gjs/wikis/Mapping
There are also a number of more complete examples here:
https://gitlab.gnome.org/GNOME/gjs/tree/master/examples