Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

console-display: Symbol.toStringTag NOT work when extends EventTarget #37329

Open
navegador5 opened this issue Feb 12, 2021 · 5 comments
Open
Labels
eventtarget Issues and PRs related to the EventTarget implementation.

Comments

@navegador5
Copy link

  • Version: v16.0.0-pre
  • Platform: linux
  • Subsystem: ubuntu

What steps will reproduce the bug?

     //worked, no extends
     class ET  {
        #tag = "empty"
        constructor(tag) {
              this.#tag = tag
        }
        get [Symbol.toStringTag]() {return(this.#tag)}
     } 
     
     > var et = new ET("uuid-xxxx")
     > et
     ET [uuid-xxxx] {}                     //I want this effect 
     >
     
     
     
     //not work , when extends 
     class ETWithSig extends EventTarget {
        #tag = "empty"
        constructor(tag) {
              super();
              this.#tag = tag
        }
        get [Symbol.toStringTag]() {return(this.#tag)}
     }
     
     
     > var xt = new ETWithSig("uuid-yyyy")
     > xt
     ETWithSig {}                          //not-work when extends 
     >

How often does it reproduce? Is there a required condition?

always

What is the expected behavior?

see the reproduce worked-example

What do you see instead?

see the reproduce extends-example

@targos targos added the util Issues and PRs related to the built-in util module. label Feb 12, 2021
@targos
Copy link
Member

targos commented Feb 12, 2021

@nodejs/util

@BridgeAR BridgeAR self-assigned this Feb 12, 2021
@BridgeAR
Copy link
Member

BridgeAR commented Feb 12, 2021

It's an issue with the custom inspect function defined for the EventTarget. These rarely mimic the regular inspect behavior.

@BridgeAR BridgeAR added eventtarget Issues and PRs related to the EventTarget implementation. and removed util Issues and PRs related to the built-in util module. labels Feb 12, 2021
@BridgeAR
Copy link
Member

I put together a "fix" but we have to be aware that it's more like a bandage. There could be way more things that do not work as expected due to not being the actual object inspected.

Anyone may feel free to open a PR with this change.

diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js
index fe588088cc..92eb22f8cd 100644
--- a/lib/internal/event_target.js
+++ b/lib/internal/event_target.js
@@ -8,6 +8,9 @@ const {
   FunctionPrototypeCall,
   NumberIsInteger,
   ObjectAssign,
+  ObjectCreate,
+  ObjectSetPrototypeOf,
+  ObjectGetPrototypeOf,
   ObjectDefineProperties,
   ObjectDefineProperty,
   ObjectGetOwnPropertyDescriptor,
@@ -32,7 +35,11 @@ const {
 } = require('internal/errors');
 const { validateObject, validateString } = require('internal/validators');
 
-const { customInspectSymbol } = require('internal/util');
+const {
+  getConstructorOf,
+  customInspectSymbol
+} = require('internal/util');
+
 const { inspect } = require('util');
 
 const kIsEventTarget = SymbolFor('nodejs.event_target');
@@ -109,15 +116,14 @@ class Event {
   }
 
   [customInspectSymbol](depth, options) {
-    const name = this.constructor.name;
     if (depth < 0)
-      return name;
+      return this;
 
     const opts = ObjectAssign({}, options, {
       depth: NumberIsInteger(options.depth) ? options.depth - 1 : options.depth
     });
 
-    return `${name} ${inspect({
+    return `${this.constructor.name} ${inspect({
       type: this[kType],
       defaultPrevented: this[kDefaultPrevented],
       cancelable: this[kCancelable],
@@ -435,16 +441,30 @@ class EventTarget {
   [kCreateEvent](nodeValue, type) {
     return new NodeCustomEvent(type, { detail: nodeValue });
   }
+
   [customInspectSymbol](depth, options) {
-    const name = this.constructor.name;
     if (depth < 0)
-      return name;
+      return this;
 
-    const opts = ObjectAssign({}, options, {
+    const opts = {
+      ...options,
       depth: NumberIsInteger(options.depth) ? options.depth - 1 : options.depth
-    });
+    };
+
+    const constructor = getConstructorOf(this) || EventTarget;
+    const object = ObjectCreate({ constructor });
+    ObjectSetPrototypeOf(object, ObjectGetPrototypeOf(this));
+    ObjectDefineProperty(
+      object,
+      SymbolToStringTag,
+      {
+        value: this[SymbolToStringTag],
+        enumerable: false,
+        writable: true
+      }
+    );
 
-    return `${name} ${inspect({}, opts)}`;
+    return inspect(object, opts);
   }
 }

@benjamingr
Copy link
Member

Just wondering - what are you doing with EventTarget?

@navegador5
Copy link
Author

@benjamingr
in my application:

  1. I need to make the each AST-NODE (from babel parse result) is a event-target,
  2. and a unique-tag is assigned(for log-collection to log-database-server) .
  3. using Symbol.toStringTag is just for console-manual-debug .

It is a automation testbed for javascripts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
eventtarget Issues and PRs related to the EventTarget implementation.
Projects
None yet
Development

No branches or pull requests

4 participants