@@ -15,6 +15,7 @@ var objectToString = Object.prototype.toString;
15
15
var functionToString = Function . prototype . toString ;
16
16
var match = String . prototype . match ;
17
17
var bigIntValueOf = typeof BigInt === 'function' ? BigInt . prototype . valueOf : null ;
18
+ var getPrototype = Object . getPrototypeOf || function ( o ) { return o . __proto__ ; } ;
18
19
19
20
var inspectCustom = require ( './util.inspect' ) . custom ;
20
21
var inspectSymbol = inspectCustom && isSymbol ( inspectCustom ) ? inspectCustom : null ;
@@ -145,9 +146,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
145
146
return markBoxed ( inspect ( String ( obj ) ) ) ;
146
147
}
147
148
if ( ! isDate ( obj ) && ! isRegExp ( obj ) ) {
149
+ var typeString = getTypeString ( obj ) ;
150
+ var prefix = typeString ? typeString + ' ' : '' ;
148
151
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 ( ', ' ) + ' }' ;
151
155
}
152
156
return String ( obj ) ;
153
157
} ;
@@ -319,3 +323,34 @@ function arrObjKeys(obj, inspect) {
319
323
}
320
324
return xs ;
321
325
}
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
+ }
0 commit comments