Skip to content

Commit 12fdb40

Browse files
Daniel Wolfljharb
Daniel Wolf
authored andcommitted
Printing the constructor name for non-plain objects
1 parent 7cb5c65 commit 12fdb40

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

index.js

+37-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var objectToString = Object.prototype.toString;
1515
var functionToString = Function.prototype.toString;
1616
var match = String.prototype.match;
1717
var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
18+
var getPrototype = Object.getPrototypeOf || function(o) { return o.__proto__; };
1819

1920
var inspectCustom = require('./util.inspect').custom;
2021
var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
@@ -145,9 +146,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
145146
return markBoxed(inspect(String(obj)));
146147
}
147148
if (!isDate(obj) && !isRegExp(obj)) {
149+
var typeString = getTypeString(obj);
150+
var prefix = typeString ? typeString + ' ' : '';
148151
var xs = arrObjKeys(obj, inspect);
149-
if (xs.length === 0) { return '{}'; }
150-
return '{ ' + xs.join(', ') + ' }';
152+
return xs.length === 0
153+
? prefix + '{}'
154+
: prefix + '{ ' + xs.join(', ') + ' }';
151155
}
152156
return String(obj);
153157
};
@@ -319,3 +323,34 @@ function arrObjKeys(obj, inspect) {
319323
}
320324
return xs;
321325
}
326+
327+
// Returns the object's constructor name or null if it is a plain object
328+
// or doesn't have a prototype.
329+
function getTypeString(o) {
330+
if (Object.prototype.toString.call(o) !== '[object Object]') return null;
331+
var prototype = getPrototype(o);
332+
if (!prototype) return null;
333+
334+
var constructorName = o.constructor ? o.constructor.name : null;
335+
var isPlainObject = constructorName === 'Object' && looksLikeObjectPrototype(prototype);
336+
if (isPlainObject) {
337+
return null;
338+
}
339+
340+
return constructorName;
341+
}
342+
343+
// Indicates whether the specified object appears to be Object.prototype,
344+
// regardless of the object's realm.
345+
function looksLikeObjectPrototype(o) {
346+
if (o === Object.prototype) return true;
347+
348+
// Cross-realm objects use a different Object, so we have to use a heuristic.
349+
return !getPrototype(o)
350+
&& o.hasOwnProperty('hasOwnProperty')
351+
&& o.hasOwnProperty('isPrototypeOf')
352+
&& o.hasOwnProperty('propertyIsEnumerable')
353+
&& o.hasOwnProperty('toLocaleString')
354+
&& o.hasOwnProperty('toString')
355+
&& o.hasOwnProperty('valueOf');
356+
}

test/typed.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
var inspect = require('../');
2+
var test = require('tape');
3+
4+
test('prototype is Object.prototype', function (t) {
5+
t.plan(1);
6+
var obj = {};
7+
t.equal(inspect(obj), '{}');
8+
});
9+
10+
test('prototype is null', function (t) {
11+
t.plan(1);
12+
var obj = Object.create(null);
13+
t.equal(inspect(obj), '{}');
14+
});
15+
16+
test('prototype from new', function (t) {
17+
t.plan(1);
18+
function Foo() {}
19+
var obj = new Foo();
20+
t.equal(inspect(obj), 'Foo {}');
21+
});

0 commit comments

Comments
 (0)