2

While trying to find a way to use nested classes in JS, I came up with this sort of thing:

class Character {
    constructor() {
        this.Info= class I {
            constructor(name,value) {
                this.name=name;
                this.value=value;   
            }
        };
    }
    bar () {
        var trial = new this.Info("Goofy", 2);
        alert(trial.name);
    }
}

var test = new Character();
test.bar();

and it seems to work. However, I'm afraid this might be creating a new function object for each new call, as I define the class in the constructor (which is executed at each new call). Is there a more efficient way of doing this?

This question does not solve my issue as the author only wonders how to even have a nested class; I'm already able to do that but I wonder if there's a more efficient way.

halfer
  • 19,824
  • 17
  • 99
  • 186
memememe
  • 663
  • 6
  • 21
  • Have you considered creating *Info* as a [static method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static) instead? – RobG Jun 09 '19 at 00:23
  • Nice one, but I guess it would mean falling back to the `function` syntax? I'd like to be able to use `class` – memememe Jun 09 '19 at 00:27
  • Possible duplicate of [Nested ES6 classes?](https://stackoverflow.com/questions/28784375/nested-es6-classes) – filipe Jun 09 '19 at 00:53
  • @filipe I've edited to explain why my question is different – memememe Jun 09 '19 at 01:05
  • So.. the most efficient way is to have it as static using any of the available nomenclature, or then just to not nest it ! – filipe Jun 09 '19 at 01:23

2 Answers2

5

Using a static property in react, angular or just using babel, because direct static class properties are not currently implemented on all browsers.

class Character {

    static Info = class I {
        constructor(name) { this.name=name; }
    }

    bar () {
        return new Character.Info("Goofy");
    }
}

const test = new Character();
console.log(test.bar());

Using a static property the old way -- currently working on all browsers.

class Character {
    bar () { return new Character.Info("Goofy"); }
}

Character.Info = class I {
    constructor(name) { this.name=name; }
}

const test = new Character();
console.log(test.bar());
filipe
  • 1,957
  • 1
  • 10
  • 23
  • Cool, I didn't find the right syntax fast enough. :-) – RobG Jun 09 '19 at 00:53
  • Raises the question: why isn't there an easy way to reference a constructor from within the constructor? That would make it easier to call static methods. – RobG Jun 09 '19 at 00:55
  • @RobG, because the object is not created yet when inside the constructor. – filipe Jun 09 '19 at 01:03
  • I get `SyntaxError: Unexpected token '='. Expected an opening '(' before a method's parameter list.` at the line `static Info = class I {`. – RobG Jun 09 '19 at 01:06
  • @RobG, In chrome its on the current spec. – filipe Jun 09 '19 at 01:10
  • 1
    Then likely not a good solution. Fails in current Edge, Safari and Firefox. :-( – RobG Jun 09 '19 at 01:21
  • @RobG, use Character.Info = class ... its the same. We all use babel, and you should start to get used of it :-) – filipe Jun 09 '19 at 01:24
  • Also do you mean you have to assign it from outside to make it work on all browsers? – memememe Jun 09 '19 at 01:31
  • 2
    "We" don't all use babel. I can't support introducing a dependency like that, it's really no better than saying "use library X". – RobG Jun 09 '19 at 01:47
  • Babel is a transpiler not a dependency. It allow you to use all the javascript current and next stuff and it will transpire the code to any browser version. Babel is usually bundled with webpack. – filipe Jun 09 '19 at 01:48
  • `static #Info = class I { constructor(name) { this.name=name; } }` makes it possible to add private classes, and this is what I was looking for. But in `class Character { static #Info = class I { constructor() {} }; a = new Character.#Info(); }`, `class I`'s constructor, is still accessible after `var c = new Character(); var i = new c.a.constructor()`. So keep members private too. – JPortillo Mar 07 '23 at 18:26
3

Maybe the example you've given is too simple to demonstrate whatever problem you're trying to solve, but it seems to me you don't need to nest them at all.

class Info {
  constructor(name, value) {
    this.name = name;
    this.value = value;
  }
}

class Character {
  bar() {
    var trial = new Info("Goofy", 2);
    console.log(trial.name);
  }
}

const test = new Character();
test.bar();
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • I completely agree. Nested classes to make it look like a namespace. Well we already have the modules. The most eficiente way to nest two classes is to not nest them! – filipe Jun 09 '19 at 01:13