skip to Main Content

For a certain reason, I have to declare my classes this way:

const core = {
    character: class {
        constructor(arg) {}
    }
}

Works pretty, but I don’t know how to extends the class ‘character’. I’m trying the way below, but it doesn’t work:

const core = {
  character: class {
    constructor(arg) {}
  },
  enemy: class extends core.character {
    constructor(arg) {}
  }
}

3

Answers


  1. You are trying to use core inside its own initialization, which is not allowed in JavaScript. To fix it, you can initialize the extended classes after the base class:

    const core = {
      character: class {
        isCharacter = true;
        constructor(arg) {}
      }
    };
    core.enemy = class extends core.character {
      isEnemy = true;
      constructor(arg) {
        super();
      }
    };
    
    console.log(new core.enemy());
    Login or Signup to reply.
  2. For the record: it’s a bit more work, but you can do things without class syntax (using composition).

    const character1 = createCharacter(`hostile`);
    const character2 = createCharacter(`friendly`);
    const character3 = createCharacter();
    
    console.log(`character1 =>`, character1);
    console.log(`character2 =>`, character2);
    console.log(`character3 =>`, character3);
    
    character2.character = `whodunnit`; // frozen, no can do
    console.log(`is character1 the enemy? ${character1.isEnemy}`);
    console.log(`is character2 the enemy? ${character2.isEnemy}`);
    console.log(`is character3 the enemy? ${character3.isEnemy}`);
    
    // ---
    function characterConstructor(chr) {
      return Object.freeze({
        character: chr ?? ``,
        isCharacter: chr?.length > 0,
      });
    }
    
    function createCharacter(character) {
      const core = clone(characterConstructor(character));
      Object.defineProperty( core, `isEnemy`, {
        get() {
          return !core.isCharacter ? `UNKNOWN` 
            : core.character === `hostile` ? `YES` : `NO`; 
        }, 
        enumerable: true, } );
      
      return Object.freeze(core);
    }
    
    function clone(obj) {
      return Object.entries(Object.getOwnPropertyDescriptors(obj ?? {}))
        .reduce((clone, [key, value]) => 
          Object.defineProperty(clone, key, value), {});
    }
    .as-console-wrapper {
      max-height: 100% !important;
    }
    Login or Signup to reply.
  3. You could simply instantiate core from a class. This seems more readable and versatile than some alternatives.

    const core = new class GameCore {
    
      // GameCore props and methods
      static version = "1.0.0";
      get name() { return this.constructor.name; }
      get version() { return this.constructor.version }
      someMethod() {}
      
      // GameCore classes
      
      Character = class {
        constructor(args) {}
        prop1 = 1;
        get name() { return this.constructor.name; }
      }
      
      Enemy = class extends this.Character {
        prop1 = 10;
        prop2 = 20;
        constructor(args) {
          super(args);
        }
      }
      
    }
    
    // Test
    
    console.log(`${core.name} version ${core.version} typeof ${typeof core}`);
    
    const character = new core.Character();
    character.prop1 += 100;
    console.log(character.name, typeof character, character);
    
    const enemy = new core.Enemy();
    enemy.prop1 += 0.5;
    console.log(enemy.name, typeof enemy, enemy)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search