Home > database >  Why is subclass [class (anonymous)]
Why is subclass [class (anonymous)]

Time:06-10

Given the example below, could someone please advise why is my C class show as anonymous? I'm trying to validate the instanceOf B.C and it's always false :(

Thank you in advance.

class A {
 constructor() {
   this.a = 1
 }
};

class B extends A {
 constructor() {
   super();
   this.a = 2;
 }
}

B.C = class extends B {
 constructor() {
   super();
   this.a = 3;
 }
}

console.log(A, B, B.C) //[class A], [class B extends A], [class (anonymous) extends B]

let test = new B.C();
console.log(test instanceof B.C) //false
console.log(test.constructor.name) //''

CodePudding user response:

In most situations, assigning an anonymous class expression to something (a variable, a property in an object initializer, the parameter name if using a class expression as the default value of the parameter, ...) assigns the name of the thing to the class. Example:

const A = class {};
console.log(A.name);          // "A"

const obj = {
    B: class {},
};
console.log(obj.B.name);      // "B"

function example(C = class {}) {
    console.log(C.name);      // "C"
}
example();

But there's a specific exception for when you're adding a property to an existing object. That was deemed a security risk by TC39 (imagine you're storing a class/function you're going to give to untrusted code using a key that should be private to your code and not exposed to theirs), so it's one of the very few places that doesn't happen:

const obj = {};
obj.A = class {};
console.log(obj.A.name); // ""

If you want B.C to have a name, give it one explicitly:

B.C = class SomeNameHere extends B {
    // ...

The same is true for anonymous function expressions, see my answer here for more on that.


In a comment on the answer you've said:

...However the instance validation is still showing as false. Any suggestions on what is causing this?...

That won't happen with the code in the question, regardless of whether B.C has a name. instanceof works just fine either way:

class A {
    constructor() {
        this.a = 1;
    }
}

class B extends A {
    constructor() {
        super();
        this.a = 2;
    }
}

// With a name
B.C = class BC extends B {
    constructor() {
        super();
        this.a = 3;
    }
};

// Without a name
B.D = class extends B {
    constructor() {
        super();
        this.a = 3;
    }
};

console.log(A, B, B.C); // [class A], [class B extends A], [class (anonymous) extends B]

let test = new B.C();
console.log(test instanceof B.C);   // true
console.log(test.constructor.name); // "BC"

let test2 = new B.D();
console.log(test2 instanceof B.D);   // true
console.log(test2.constructor.name); // ""
.as-console-wrapper {
    max-height: 100% !important;
}

CodePudding user response:

Your last class is anonymus, becasue you never giving it the name C. You are just create a property called C containing the anonymus class.

I think the syntax for what you are expecting would look like this:

...

class C extends B {
 constructor() {
   super();
   this.a = 3;
 }
}

var B = new B();
B.C = new C();

In this way you are defining a new class called C and add a new property also called C to B and fill it with an instance of C.

  • Related