Skip to content

Commit 51c9014

Browse files
author
Daniel Wolf
committed
Printing the constructor name for non-plain objects
1 parent 71e24db commit 51c9014

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
@@ -8,6 +8,7 @@ var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'f
88
var setForEach = hasSet && Set.prototype.forEach;
99
var booleanValueOf = Boolean.prototype.valueOf;
1010
var objectToString = Object.prototype.toString;
11+
var getPrototype = Object.getPrototypeOf || function(o) { return o.__proto__; };
1112

1213
var inspectCustom = require('./util.inspect').custom;
1314
var inspectSymbol = (inspectCustom && isSymbol(inspectCustom)) ? inspectCustom : null;
@@ -112,9 +113,12 @@ module.exports = function inspect_ (obj, opts, depth, seen) {
112113
return markBoxed(inspect(String(obj)));
113114
}
114115
if (!isDate(obj) && !isRegExp(obj)) {
116+
var typeString = getTypeString(obj);
117+
var prefix = typeString ? typeString + ' ' : '';
115118
var xs = arrObjKeys(obj, inspect);
116-
if (xs.length === 0) return '{}';
117-
return '{ ' + xs.join(', ') + ' }';
119+
return xs.length === 0
120+
? prefix + '{}'
121+
: prefix + '{ ' + xs.join(', ') + ' }';
118122
}
119123
return String(obj);
120124
};
@@ -237,3 +241,34 @@ function arrObjKeys (obj, inspect) {
237241
}
238242
return xs;
239243
}
244+
245+
// Returns the object's constructor name or null if it is a plain object
246+
// or doesn't have a prototype.
247+
function getTypeString(o) {
248+
if (Object.prototype.toString(o) !== '[object Object]') return null;
249+
var prototype = getPrototype(o);
250+
if (!prototype) return null;
251+
252+
var constructorName = o.constructor ? o.constructor.name : null;
253+
var isPlainObject = constructorName === 'Object' && looksLikeObjectPrototype(prototype);
254+
if (isPlainObject) {
255+
return null;
256+
}
257+
258+
return constructorName;
259+
}
260+
261+
// Indicates whether the specified object appears to be Object.prototype,
262+
// regardless of the object's realm.
263+
function looksLikeObjectPrototype(o) {
264+
if (o === Object.prototype) return true;
265+
266+
// Cross-realm objects use a different Object, so we have to use a heuristic.
267+
return !getPrototype(o)
268+
&& o.hasOwnProperty('hasOwnProperty')
269+
&& o.hasOwnProperty('isPrototypeOf')
270+
&& o.hasOwnProperty('propertyIsEnumerable')
271+
&& o.hasOwnProperty('toLocaleString')
272+
&& o.hasOwnProperty('toString')
273+
&& o.hasOwnProperty('valueOf');
274+
}

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)