Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Do these 2 additional things when using ES6 class inheritance aliasing
- * without directly typing prototypes:
- * 1. Add the following code right below a new class inheriting another one:
- * - ExtendedClassAlias.inherit(Klass);
- * Where Klass is the new class inheriting another one
- * 2. Add the following code right below extending an existing class as a way
- * to alias its methods:
- * - ExtendedClassAlias.updateClass(Klass);
- * Where Klass is the existing class being extended as a way to alias its
- * methods
- * Right now it doesn't work well with inheriting static functions in classes,
- * so those in children classes should use ParentClass.staticFunc.call(this)
- * instead of super.staticFunc()
- */
- // Codes allowing ES6 class inheritance aliasing without direct prototyping
- class ExtendedClassAlias {
- static inherit(Child) {
- const childProto = Child.prototype;
- const parentName = Object.getPrototypeOf(childProto).constructor.name;
- this._inherit(Child, parentName);
- }
- static updateClass(Parent) {
- const parentName = Parent.prototype.constructor.name;
- // There's no need to update anything if the passed class's no children
- if (!this._inheritances.has(parentName)) return;
- this._updateClass(this._inheritances.get(parentName), Parent);
- //
- }
- static _inherit(Child, parentName) {
- // So the parent class will know which classes are its children
- if (this._inheritances.has(parentName)) {
- const oldChildProtos = this._inheritances.get(parentName);
- const newChildProtos = oldChildProtos.concat([Child]);
- this._inheritances.set(parentName, newChildProtos);
- } else {
- this._inheritances.set(parentName, [Child]);
- }
- //
- }
- static _updateClass(children, Parent) {
- this._updateProtoMethods(children, Parent.prototype);
- this._updateStaticFuncs(children, Parent);
- }
- static _updateProtoMethods(children, parentProto) {
- // So all the children will inherit the new rather than the old parent
- children.forEach(Child => Child.prototype.__proto__ = parentProto);
- //
- }
- static _updateStaticFuncs(children, Parent) {
- // So all children will inherit all new static functions from new parent
- Object.getOwnPropertyNames(Parent).forEach(name => {
- const desc = Object.getOwnPropertyDescriptor(Parent, name);
- if (!desc || typeof desc.value !== "function") return;
- children.forEach(Child => {
- Child[name] = Child[name] || Parent[name];
- });
- });
- //
- }
- }
- ExtendedClassAlias._inheritances = new Map();
- //
- // Default RMMZ codebase
- class DefaultMZSuperClass {
- static reusedStaticFunc() { return "Super reused static function"; }
- static overridenStaticFunc() { return "Super overriden static function"; }
- static unusedStaticFunc() { return "Super unused static function"; }
- constructor(superVal) { this._superVal = superVal; }
- reusedMethod() { return `Super reused method superVal: ${this._superVal}`; }
- overridenMethod() { return "Super overriden method"; }
- unusedMethod() { return "Super unused method"; }
- }
- class DefaultMZBaseClass extends DefaultMZSuperClass {
- static reusedStaticFunc() {
- const reused = DefaultMZSuperClass.reusedStaticFunc();
- return `${reused} Base reused static function`;
- }
- static overridenStaticFunc() { return "Base overriden static function"; }
- static baseNewStaticFunc() { return "Base base new static function"; }
- constructor(superVal, baseVal) {
- super(superVal);
- this._baseVal = baseVal;
- }
- reusedMethod() {
- const reused = super.reusedMethod();
- return `${reused} Base reused method baseVal: ${this._baseVal}`;
- }
- overridenMethod() { return "Base overriden method"; }
- baseReusedMethod() {
- return `Base base reused method baseVal: ${this._baseVal}`;
- }
- baseOverridenMethod() { return "Base base overriden method"; }
- baseUnusedMethod() {
- return `Base base unused method superVal: ${this._superVal}`;
- }
- setBaseSuper(baseSuper) { this._superVal = baseSuper; }
- }
- ExtendedClassAlias.inherit(DefaultMZBaseClass);
- class DefaultMZParentClass extends DefaultMZSuperClass {
- static reusedStaticFunc() {
- const reused = DefaultMZSuperClass.reusedStaticFunc();
- return `${reused} Parent reused static function`;
- }
- static overridenStaticFunc() { return "Parent overriden static function"; }
- static parentNewStaticFunc() { return "Parent parent new static function"; }
- constructor(superVal, parentVal) {
- super(superVal);
- this._parentVal = parentVal;
- }
- reusedMethod() {
- const reused = super.reusedMethod();
- return `${reused} Parent reused method parentVal: ${this._parentVal}`;
- }
- overridenMethod() { return "Parent overriden method"; }
- parentReusedMethod() {
- return `Parent parent reused method parentVal: ${this._parentVal}`;
- }
- parentOverridenMethod() { return "Parent parent overriden method"; }
- parentUnusedMethod() {
- return `Parent parent unused method superVal: ${this._superVal}`;
- }
- setParentSuper(parentSuper) { this._superVal = parentSuper; }
- }
- ExtendedClassAlias.inherit(DefaultMZParentClass);
- class DefaultMZChildClass extends DefaultMZParentClass {
- constructor(superVal, parentVal, childVal) {
- super(superVal, parentVal);
- this._childVal = childVal;
- }
- parentReusedMethod() {
- const reused = super.parentReusedMethod(), childVal = this._childVal;
- return `${reused} Child parent reused method childVal: ${childVal}`;
- }
- parentOverridenMethod() {
- return `Child parent overriden method parentVal: ${this._parentVal}`;
- }
- childNewMethod() {
- return `Child child new method childVal: ${this._childVal}`;
- }
- setChildParent(childParent) { this._parentVal = childParent; }
- }
- ExtendedClassAlias.inherit(DefaultMZChildClass);
- //
- // Plugin A codebase
- const PluginASuperClass = DefaultMZSuperClass;
- DefaultMZSuperClass = class extends DefaultMZSuperClass {
- static reusedStaticFunc() { return `${super.reusedStaticFunc()} Plugin A`; }
- static overridenStaticFunc() {
- return "Plugin A Super overriden static function";
- }
- static pluginASuperNewStaticFunc() {
- return "Plugin A plugin a super new static function";
- }
- reusedMethod() { return `${super.reusedMethod()} Plugin A`; }
- overridenMethod() { return "Plugin A Super overriden method"; }
- pluginASuperNewMethod() {
- return `Plugin A plugin a super new method superVal: ${this._superVal}`;
- }
- setPluginA(pluginA) { this._pluginA = pluginA; }
- };
- ExtendedClassAlias.updateClass(DefaultMZSuperClass);
- const PluginAParentClass = DefaultMZParentClass;
- DefaultMZParentClass = class extends DefaultMZParentClass {
- static reusedStaticFunc() { return `Plugin A ${super.reusedStaticFunc()}`; }
- static overridenStaticFunc() {
- return "Parent overriden static function Plugin A";
- }
- reusedMethod() { return `Plugin A ${super.reusedMethod()}`; }
- overridenMethod() { return "Parent overriden method Plugin A"; }
- setParentSuper(parentSuper) {
- super.setParentSuper(`plugin a ${parentSuper} Plugin A`);
- }
- showPluginA() { return `show plugin a pluginA: ${this._pluginA}`; }
- };
- ExtendedClassAlias.updateClass(DefaultMZParentClass);
- class PluginAMasterClass {
- static showMaster() { return "PluginAMasterClass"; }
- constructor(masterVal) { this.setMaster(masterVal); }
- getMaster() {
- return `PluginAMasterClass getMaster master: ${this._masterVal}`;
- }
- setMaster(masterVal) { this._masterVal = masterVal; }
- }
- class PluginABaseClass extends DefaultMZBaseClass {
- constructor(superVal, baseVal, pluginAVal) {
- super(superVal, baseVal);
- this._pluginAVal = pluginAVal;
- }
- reusedMethod() {
- const reused = super.reusedMethod();
- const pluginAVal = this._pluginAVal;
- return `${reused} Plugin A reused method pluginAVal: ${pluginAVal}`;
- }
- baseOverridenMethod() { return "Plugin A base overriden method"; }
- pluginABaseNewMethod() {
- const pluginAVal = this._pluginAVal;
- return `Plugin A plugin a base new method pluginAVal: ${pluginAVal}`;
- }
- }
- ExtendedClassAlias.inherit(PluginABaseClass);
- //
- // Plugin B codebase
- const PluginBSuperClass = DefaultMZSuperClass;
- DefaultMZSuperClass = class extends DefaultMZSuperClass {
- static reusedStaticFunc() { return `${super.reusedStaticFunc()} Plugin B`; }
- static overridenStaticFunc() {
- return "Plugin B Super overriden static function";
- }
- static pluginBSuperNewStaticFunc() {
- return "Plugin B plugin b super new static function";
- }
- reusedMethod() { return `${super.reusedMethod()} Plugin B`; }
- overridenMethod() { return "Plugin B Super overriden method"; }
- pluginBSuperNewMethod() {
- return `Plugin B plugin b super new method superVal: ${this._superVal}`;
- }
- setPluginB(pluginB) { this._pluginB = pluginB; }
- };
- ExtendedClassAlias.updateClass(DefaultMZSuperClass);
- const PluginBParentClass = DefaultMZParentClass;
- DefaultMZParentClass = class extends DefaultMZParentClass {
- static reusedStaticFunc() { return `Plugin B ${super.reusedStaticFunc()}`; }
- static overridenStaticFunc() {
- return "Parent overriden static function Plugin B";
- }
- reusedMethod() { return `Plugin B ${super.reusedMethod()}`; }
- overridenMethod() { return "Parent overriden method Plugin B"; }
- setParentSuper(parentSuper) {
- super.setParentSuper(`plugin b ${parentSuper} Plugin B`);
- }
- showPluginB() { return `show plugin b pluginB: ${this._pluginB}`; }
- };
- ExtendedClassAlias.updateClass(DefaultMZParentClass);
- class PluginBMasterClass {
- static showMaster() { return "PluginBMasterClass"; }
- constructor(masterVal) { this.setMaster(masterVal); }
- getMaster() {
- return `PluginBMasterClass getMaster master: ${this._masterVal}`;
- }
- setMaster(masterVal) { this._masterVal = masterVal; }
- }
- class PluginBBaseClass extends DefaultMZBaseClass {
- constructor(superVal, baseVal, pluginBVal) {
- super(superVal, baseVal);
- this._pluginBVal = pluginBVal;
- }
- reusedMethod() {
- const reused = super.reusedMethod();
- const pluginBVal = this._pluginBVal;
- return `${reused} Plugin B reused method pluginBVal: ${pluginBVal}`;
- }
- baseOverridenMethod() { return "Plugin B base overriden method"; }
- pluginBBaseNewMethod() {
- const pluginBVal = this._pluginBVal;
- return `Plugin B plugin b base new method pluginBVal: ${pluginBVal}`;
- }
- }
- ExtendedClassAlias.inherit(PluginBBaseClass);
- //
- const showMethods = (methodNames, classInstance) => {
- methodNames.forEach(methodName => showMethod(classInstance, methodName));
- };
- const showMethod = (classInstance, methodName) => {
- const className = (classInstance.prototype || classInstance).constructor.name;
- console.info(`${className}.${methodName}: ${classInstance[methodName]()}`);
- };
- // Tests static functions in classes
- const superStaticFuncNames = [
- "reusedStaticFunc",
- "overridenStaticFunc",
- "unusedStaticFunc",
- "pluginASuperNewStaticFunc",
- "pluginBSuperNewStaticFunc"
- ];
- [
- DefaultMZSuperClass,
- DefaultMZBaseClass,
- DefaultMZParentClass,
- DefaultMZChildClass,
- PluginABaseClass,
- PluginBBaseClass
- ].forEach(Klass => showMethods(superStaticFuncNames, Klass));
- [DefaultMZBaseClass, PluginABaseClass, PluginBBaseClass].forEach(Klass => {
- showMethod(Klass, "baseNewStaticFunc");
- });
- [DefaultMZParentClass, DefaultMZChildClass].forEach(Klass => {
- showMethod(Klass, "parentNewStaticFunc");
- });
- [PluginAMasterClass, PluginBMasterClass].forEach(Klass => {
- showMethod(Klass, "showMaster");
- });
- //
- console.info("\n");
- // Tests prototype methods in classes
- const superClass = new DefaultMZSuperClass("super");
- const baseClass = new DefaultMZBaseClass("super", "base");
- const parentClass = new DefaultMZParentClass("super", "parent");
- const childClass = new DefaultMZChildClass("super", "parent", "child");
- const pluginAClass = new PluginABaseClass("super", "base", "pluginA");
- const pluginBClass = new PluginBBaseClass("super", "base", "pluginB");
- const pluginAMasterClass = new PluginAMasterClass("pluginAMaster");
- const pluginBMasterClass = new PluginBMasterClass("pluginBMaster");
- const superMethodNames = [
- "reusedMethod",
- "overridenMethod",
- "unusedMethod",
- "pluginASuperNewMethod",
- "pluginBSuperNewMethod"
- ];
- const baseMethodNames = [
- "baseReusedMethod",
- "baseOverridenMethod",
- "baseUnusedMethod"
- ];
- const parentMethodNames = [
- "parentReusedMethod",
- "parentOverridenMethod",
- "parentUnusedMethod",
- "showPluginA",
- "showPluginB"
- ];
- [
- superClass,
- baseClass,
- parentClass,
- childClass,
- pluginAClass,
- pluginBClass
- ].forEach(classInstance => showMethods(superMethodNames, classInstance));
- [baseClass, pluginAClass, pluginBClass].forEach(classInstance => {
- showMethods(baseMethodNames, classInstance);
- classInstance.setBaseSuper("base super");
- showMethods(baseMethodNames, classInstance);
- });
- showMethod(pluginAClass, "pluginABaseNewMethod");
- showMethod(pluginBClass, "pluginBBaseNewMethod");
- [parentClass, childClass].forEach(classInstance => {
- showMethods(parentMethodNames, classInstance);
- classInstance.setParentSuper("parent super");
- classInstance.setPluginA("pluginA");
- classInstance.setPluginB("pluginB");
- showMethods(parentMethodNames, classInstance);
- });
- [pluginAMasterClass, pluginBMasterClass].forEach(classInstance => {
- showMethod(classInstance, "getMaster");
- });
- pluginAMasterClass.setMaster("masterPluginA");
- pluginBMasterClass.setMaster("masterPluginB");
- [pluginAMasterClass, pluginBMasterClass].forEach(classInstance => {
- showMethod(classInstance, "getMaster");
- });
- showMethod(childClass, "childNewMethod");
- //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement