patterns | , making a class the normal way | enforcing an interface | Search

This module exports two functions, extend and override, which create a new class by inheriting properties from a parent class, allowing for property overriding and extension. The functions are demonstrated through example usage and unit tests, showcasing their functionality and flexibility.

Run example

npm run import -- "extend prototype class"

extend prototype class

var parentObj = {
    do_init() {
        console.log('parent');
    },
    do_message() {
        console.log('original');
    }
}

var childObj = {
    do_init() {
        console.log('child');
        parentObj.do_init();
    },
    do_message() {
        parentObj.do_message();
        console.log('overridden');
    }
}

function extend(child, parent) {
    var newClass = Object.create(parent || {});
    Object.assign(newClass, child, Object.getPrototypeOf(child || {}));
    var self = Object.create(newClass);
    return self;
}

function override(child) {
    return extend(child, this);
}

module.exports = {
    extend,
    override
}
//module.exports = Object.create.bind(null, childObj)

if(typeof $ !== 'undefined') {
    console.log(typeof module.exports)
    var testClass = module.exports.extend();
    console.log(typeof testClass.do_init)
    testClass = module.exports.extend(childObj, parentObj)
    testClass.do_init();
    testClass.do_message();
    testClass = module.exports.extend({}, parentObj)
    testClass.do_init();
    testClass.do_message();
    // TODO: more tests
    
    /* expected output
    object
    undefined
    child
    parent
    original
    overridden
    parent
    original
    */
}

What the code could have been:

// Define a base class with a method for initialization and a method for sending a message
class BaseClass {
  /**
   * Initializes the class by logging a message to the console
   */
  doInit() {
    console.log('base');
  }

  /**
   * Sends a message by logging a message to the console
   * @returns {string} The original message
   */
  doMessage() {
    console.log('original');
    return 'original';
  }
}

// Define a class that extends the base class and overrides the doMessage method
class ChildClass extends BaseClass {
  /**
   * Initializes the class by calling the parent's doInit method and logging a message
   */
  doInit() {
    super.doInit();
    console.log('child');
  }

  /**
   * Overloads the doMessage method to log an additional message
   * @returns {string} The original message
   */
  doMessage() {
    const originalMessage = super.doMessage();
    console.log('overridden');
    return originalMessage;
  }
}

// Define an extend function to create a new class that inherits from an existing class
class ClassExtender {
  /**
   * Creates a new class that inherits from the specified parent class
   * @param {Object} child The child class to extend
   * @param {Object} parent The parent class to inherit from
   * @returns {Object} A new class that inherits from the parent class
   */
  static extend(child, parent = {}) {
    return class NewClass extends parent {
      constructor(...args) {
        super(...args);
        Object.assign(this, child);
      }
    }
  }
}

// Define an override function to create a new class that inherits from the current class
class ClassOverrider {
  /**
   * Creates a new class that inherits from the current class
   * @returns {Object} A new class that inherits from the current class
   */
  static override() {
    return ClassExtender.extend(this);
  }
}

// Test the ClassExtender and ClassOverrider classes
const extender = new ClassExtender();
const overrider = new ClassOverrider();

// Create a new class that inherits from the base class
const testClass = extender.extend();

// Test the doInit and doMessage methods
console.log(typeof testClass.doInit); // Should be undefined
testClass = extender.extend(ChildClass, BaseClass);
testClass.doInit();
testClass.doMessage();

// Create a new class that inherits from the base class without a parent class
testClass = extender.extend({}, BaseClass);
testClass.doInit();
testClass.doMessage();

// Create a new class that inherits from the base class using the override function
testClass = overrider.override();
testClass.doInit();
testClass.doMessage();

Overview

This code defines a module that exports two functions, extend and override, which are used to create a new class by inheriting properties from a parent class. The code also includes unit tests to demonstrate the functionality.

Functions

extend(child, parent)

override(child)

Example Usage

var parentObj = {
    do_init() {
        console.log('parent');
    },
    do_message() {
        console.log('original');
    }
}

var childObj = {
    do_init() {
        console.log('child');
        parentObj.do_init();
    },
    do_message() {
        parentObj.do_message();
        console.log('overridden');
    }
}

var newClass = module.exports.extend(childObj, parentObj);
newClass.do_init(); // outputs: child, parent
newClass.do_message(); // outputs: original, overridden

Tests

The code includes a test section to demonstrate the functionality of the extend and override functions.

if(typeof $!== 'undefined') {
    //...
}

The test creates a new class using the extend function with no parent object and checks that the resulting class has a do_init method. It then creates a new class using the extend function with the childObj and parentObj objects as arguments and checks that it inherits the correct behavior. Finally, it creates a new class using the extend function with an empty child object and the parentObj object as arguments and checks that it inherits the correct behavior.