@@ -8,6 +8,7 @@ var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'f
8
8
var setForEach = hasSet && Set . prototype . forEach ;
9
9
var booleanValueOf = Boolean . prototype . valueOf ;
10
10
var objectToString = Object . prototype . toString ;
11
+ var getPrototype = Object . getPrototypeOf || function ( o ) { return o . __proto__ ; } ;
11
12
12
13
var inspectCustom = require ( './util.inspect' ) . custom ;
13
14
var inspectSymbol = ( inspectCustom && isSymbol ( inspectCustom ) ) ? inspectCustom : null ;
@@ -112,9 +113,12 @@ module.exports = function inspect_ (obj, opts, depth, seen) {
112
113
return markBoxed ( inspect ( String ( obj ) ) ) ;
113
114
}
114
115
if ( ! isDate ( obj ) && ! isRegExp ( obj ) ) {
116
+ var typeString = getTypeString ( obj ) ;
117
+ var prefix = typeString ? typeString + ' ' : '' ;
115
118
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 ( ', ' ) + ' }' ;
118
122
}
119
123
return String ( obj ) ;
120
124
} ;
@@ -237,3 +241,34 @@ function arrObjKeys (obj, inspect) {
237
241
}
238
242
return xs ;
239
243
}
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
+ }
0 commit comments