Inheritable Top-level Classes
"use strict";
Object.defineProperty(window, "BaseObject", {
value: (() => {
let nil = Object.freeze(Object.create(null));
Object.defineProperty(window, "Nil", {
value: (() => {
function Nil() {}
Nil.prototype = nil;
return Nil;
})(),
writable: false,
enumerable: false,
configurable: false
});
// (nil !== nil) => true
// (nil instanceof Nil) => true
// (nil.prop = "val"; nil.prop) => undefined
Object.defineProperty(window, "nil", {
get: function () {
return Object.freeze(new Nil());
},
set: function () {
throw new Error("Cannot overwrite nil");
},
enumerable: false,
configurable: false
});
class BaseObject extends Nil {
constructor() {
super();
// non-enumerable [fixes JSON.stringify bug]
Object.defineProperty(this, "__proto__", {
value: BaseObject.prototype,
writable: false,
enumerable: false,
configurable: false
});
}
toString() {
return `[object ${this.constructor.name}]`;
}
toJson() {
return JSON.stringify(Object.assign({
"__class__": this.constructor.name
}, this));
}
}
BaseObject.fromJson = obj => {
return Object.assign(new BaseObject(), JSON.parse(obj));
};
return BaseObject;
})(),
writable: false,
enumerable: false,
configurable: false
});
class Entity extends BaseObject {
constructor(name = "Steve") {
super();
this.name = name;
}
sayHi() {
console.log(`Hi! My name is ${this.name}`);
}
}
// Entity.fromJson = undefined;
Entity.fromJson = obj => {
let parsed = JSON.parse(obj);
delete parsed["__class__"];
return Object.assign(new Entity(parsed && parsed.name), parsed);
};