Skip to content

Commit

Permalink
Printing the constructor name for non-plain objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Wolf committed Nov 10, 2017
1 parent 71e24db commit 51c9014
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
39 changes: 37 additions & 2 deletions index.js
Expand Up @@ -8,6 +8,7 @@ var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'f
var setForEach = hasSet && Set.prototype.forEach;
var booleanValueOf = Boolean.prototype.valueOf;
var objectToString = Object.prototype.toString;
var getPrototype = Object.getPrototypeOf || function(o) { return o.__proto__; };

var inspectCustom = require('./util.inspect').custom;
var inspectSymbol = (inspectCustom && isSymbol(inspectCustom)) ? inspectCustom : null;
Expand Down Expand Up @@ -112,9 +113,12 @@ module.exports = function inspect_ (obj, opts, depth, seen) {
return markBoxed(inspect(String(obj)));
}
if (!isDate(obj) && !isRegExp(obj)) {
var typeString = getTypeString(obj);
var prefix = typeString ? typeString + ' ' : '';
var xs = arrObjKeys(obj, inspect);
if (xs.length === 0) return '{}';
return '{ ' + xs.join(', ') + ' }';
return xs.length === 0
? prefix + '{}'
: prefix + '{ ' + xs.join(', ') + ' }';
}
return String(obj);
};
Expand Down Expand Up @@ -237,3 +241,34 @@ function arrObjKeys (obj, inspect) {
}
return xs;
}

// Returns the object's constructor name or null if it is a plain object
// or doesn't have a prototype.
function getTypeString(o) {
if (Object.prototype.toString(o) !== '[object Object]') return null;
var prototype = getPrototype(o);
if (!prototype) return null;

var constructorName = o.constructor ? o.constructor.name : null;
var isPlainObject = constructorName === 'Object' && looksLikeObjectPrototype(prototype);
if (isPlainObject) {
return null;
}

return constructorName;
}

// Indicates whether the specified object appears to be Object.prototype,
// regardless of the object's realm.
function looksLikeObjectPrototype(o) {
if (o === Object.prototype) return true;

// Cross-realm objects use a different Object, so we have to use a heuristic.
return !getPrototype(o)
&& o.hasOwnProperty('hasOwnProperty')
&& o.hasOwnProperty('isPrototypeOf')
&& o.hasOwnProperty('propertyIsEnumerable')
&& o.hasOwnProperty('toLocaleString')
&& o.hasOwnProperty('toString')
&& o.hasOwnProperty('valueOf');
}
21 changes: 21 additions & 0 deletions test/typed.js
@@ -0,0 +1,21 @@
var inspect = require('../');
var test = require('tape');

test('prototype is Object.prototype', function (t) {
t.plan(1);
var obj = {};
t.equal(inspect(obj), '{}');
});

test('prototype is null', function (t) {
t.plan(1);
var obj = Object.create(null);
t.equal(inspect(obj), '{}');
});

test('prototype from new', function (t) {
t.plan(1);
function Foo() {}
var obj = new Foo();
t.equal(inspect(obj), 'Foo {}');
});

0 comments on commit 51c9014

Please sign in to comment.