diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 4e8e4d47302b08..256a4a8b06904b 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -322,7 +322,7 @@ function getEmptyFormatArray() { return []; } -function getConstructorName(obj) { +function getConstructorName(obj, ctx) { let firstProto; while (obj) { const descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor'); @@ -341,10 +341,11 @@ function getConstructorName(obj) { if (firstProto === null) { return null; } - // TODO(BridgeAR): Improve prototype inspection. - // We could use inspect on the prototype itself to improve the output. - return ''; + return `<${inspect(firstProto, { + ...ctx, + customInspect: false + })}>`; } function getPrefix(constructor, tag, fallback) { @@ -503,7 +504,7 @@ function formatValue(ctx, value, recurseTimes) { } if (ctx.stop !== undefined) { - const name = getConstructorName(value) || value[Symbol.toStringTag]; + const name = getConstructorName(value, ctx) || value[Symbol.toStringTag]; return ctx.stylize(`[${name || 'Object'}]`, 'special'); } @@ -547,7 +548,7 @@ function formatValue(ctx, value, recurseTimes) { function formatRaw(ctx, value, recurseTimes) { let keys; - const constructor = getConstructorName(value); + const constructor = getConstructorName(value, ctx); let tag = value[Symbol.toStringTag]; if (typeof tag !== 'string') tag = ''; diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 20b03d2dd0297b..0d9cbdbe9d25fe 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1738,19 +1738,34 @@ assert.strictEqual( ); } -// Manipulate the prototype to one that we can not handle. +// Manipulate the prototype in weird ways. { let obj = { a: true }; let value = (function() { return function() {}; })(); Object.setPrototypeOf(value, null); Object.setPrototypeOf(obj, value); - assert.strictEqual(util.inspect(obj), '{ a: true }'); + assert.strictEqual(util.inspect(obj), '<[Function]> { a: true }'); + assert.strictEqual( + util.inspect(obj, { colors: true }), + '<\u001b[36m[Function]\u001b[39m> { a: \u001b[33mtrue\u001b[39m }' + ); obj = { a: true }; value = []; Object.setPrototypeOf(value, null); Object.setPrototypeOf(obj, value); - assert.strictEqual(util.inspect(obj), '{ a: true }'); + assert.strictEqual( + util.inspect(obj), + '<[Array: null prototype] []> { a: true }' + ); + + function StorageObject() {} + StorageObject.prototype = Object.create(null); + assert.strictEqual( + util.inspect(new StorageObject()), + '<[Object: null prototype] {}> {}' + ); + } // Check that the fallback always works.