Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix to not call unnecessary hasOwnProperty
  • Loading branch information
islandryu committed Apr 14, 2025
commit 412347c141a2d8a429ed359a649e69ff9e3519d7
33 changes: 21 additions & 12 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2160,18 +2160,23 @@ function hasBuiltInToString(value) {
}
value = proxyTarget;
}
// Count objects without `toString` and `Symbol.toPrimitive` function as built-in.
if (typeof value.toString !== 'function' && typeof value[SymbolToPrimitive] !== 'function') {
return true;
}

// The object has a own `toString` property. Thus it's not not a built-in one.
if (ObjectPrototypeHasOwnProperty(value, 'toString')) {
return false;
}
let hasOwnToString = ObjectPrototypeHasOwnProperty;
let hasOwnToPrimitive = ObjectPrototypeHasOwnProperty;

// The object has a own `Symbol.toPrimitive` property. Thus it's not not a built-in one.
if (ObjectPrototypeHasOwnProperty(value, SymbolToPrimitive)) {
// Count objects without `toString` and `Symbol.toPrimitive` function as built-in.
if (typeof value.toString !== 'function') {
if (typeof value[SymbolToPrimitive] !== 'function') {
return true;
} else if (ObjectPrototypeHasOwnProperty(value, SymbolToPrimitive)) {
return false;
}
hasOwnToString = returnFalse;
} else if (ObjectPrototypeHasOwnProperty(value, 'toString')) {
return false;
} else if (typeof value[SymbolToPrimitive] !== 'function') {
hasOwnToPrimitive = returnFalse;
} else if (ObjectPrototypeHasOwnProperty(value, SymbolToPrimitive)) {
return false;
}

Expand All @@ -2180,8 +2185,8 @@ function hasBuiltInToString(value) {
let pointer = value;
do {
pointer = ObjectGetPrototypeOf(pointer);
} while (!ObjectPrototypeHasOwnProperty(pointer, 'toString') &&
!ObjectPrototypeHasOwnProperty(pointer, SymbolToPrimitive));
} while (!hasOwnToString(pointer, 'toString') &&
!hasOwnToPrimitive(pointer, SymbolToPrimitive));

// Check closer if the object is a built-in.
const descriptor = ObjectGetOwnPropertyDescriptor(pointer, 'constructor');
Expand All @@ -2190,6 +2195,10 @@ function hasBuiltInToString(value) {
builtInObjects.has(descriptor.value.name);
}

function returnFalse() {
return false;
}
Comment on lines +2198 to +2200
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this faster than nulling out hasOwnToPrimitive and checking for that, avoiding the function call?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That likely depends on a) the inlining and b) if it is more common to have to check for both methods (if that's the case, any additional check is more expensive).


const firstErrorLine = (error) => StringPrototypeSplit(error.message, '\n', 1)[0];
let CIRCULAR_ERROR_MESSAGE;
function tryStringify(arg) {
Expand Down