diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index db54e232aa8a5b..d20c7b93c92ceb 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -574,8 +574,15 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { const constructor = getConstructorName(value, ctx); let tag = value[Symbol.toStringTag]; - if (typeof tag !== 'string') + // Only list the tag in case it's non-enumerable / not an own property. + // Otherwise we'd print this twice. + if (typeof tag !== 'string' || + tag !== '' && + (ctx.showHidden ? hasOwnProperty : propertyIsEnumerable)( + value, Symbol.toStringTag + )) { tag = ''; + } let base = ''; let formatter = getEmptyFormatArray; let braces; diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index eeda567e0d3e22..82f773d62cfe9f 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1267,8 +1267,20 @@ util.inspect(process); { // @@toStringTag - assert.strictEqual(util.inspect({ [Symbol.toStringTag]: 'a' }), - "Object [a] { [Symbol(Symbol.toStringTag)]: 'a' }"); + const obj = { [Symbol.toStringTag]: 'a' }; + assert.strictEqual( + util.inspect(obj), + "{ [Symbol(Symbol.toStringTag)]: 'a' }" + ); + Object.defineProperty(obj, Symbol.toStringTag, { + value: 'a', + enumerable: false + }); + assert.strictEqual(util.inspect(obj), 'Object [a] {}'); + assert.strictEqual( + util.inspect(obj, { showHidden: true }), + "{ [Symbol(Symbol.toStringTag)]: 'a' }" + ); class Foo { constructor() {