question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`isObject` should not allocate

See original GitHub issue

What is the Problem Being Solved?

Marshaling uses isObject on every marshalled element to determine whether it needs to be handled specially. The current test is robust against future changes to the JS spec, but allocates in most circumstances. As a result, the test is (expected to be) horrifically expensive.

Description of the Design

We use isObject so that we can change that test in one place. We should take advantage of that now to make the test non-allocating given the current JS spec. Change it to

export const isObject = val => val !== null &&  typeof val === 'object' || typeof val === 'function';

For usability, we should also add isPrimitive as the dual of isObject. Many uses would be much more readable as a result.

Security Considerations

The test must be updated if future versions of the language add more typeof cases that are not primitives.

Test Plan

Rerun tests with the isObject definition changed.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
mhofmancommented, Apr 11, 2022

Here are 2 variations of a suggestion, that should be as safe as the current always allocating Object(value) === value:

const isObject = value => {
  switch (typeof value) {
    case 'undefined':
      // [[IsHTMLDDA]]
      return value !== undefined;
    case 'boolean':
    case 'number':
    case 'string':
    case 'bigint':
    case 'symbol':
      return false;
    default:
      return value !== null && Object(value) === value;
  }
};

or

const knownSafePrimitives = freeze({
  __proto__: null,
  boolean: true,
  number: true,
  string: true,
  bigint: true,
  symbol: true,
  undefined: false,
  object: false,
  function: false,
});
const isObject = value =>
  !knownSafePrimitives[typeof value] &&
  value !== undefined && // [[IsHTMLDDA]] has typeof 'undefined'
  value !== null && // null has typeof 'object'
  Object(value) === value;
0reactions
kriskowalcommented, Apr 13, 2022

Please reopen if I’ve misunderstood the substance of the conversation above.

My understanding from above benchmark is that isObject proves to be the fastest option on both XS and V8 of all the options that are safe in the face of language change. Between Endo and Agoric SDK, we define isObject in ses and marshal and they are both already sorted.

Thank you @gibson042. Benchmarks are full of surprises!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Distinguish if C++ object was dynamically allocated or not?
No, it is not possible to detect whether an object has been allocated statically or dynamically. At least in the sense that most...
Read more >
IsObject() - Syntax & Usage - AutoHotkey
The IsObject function returns a non-zero number if the specified value is an object. ... those which do not derive from Object, such...
Read more >
Is Object In Use? - Google Groups
Hello. One thing you can do is allocate a message queue. Then check to see if that is allocated before you run it,...
Read more >
Difference Between Class and Object in OOPs - Guru99
A class is a logical entity, while an object is a physical entity. A class does not allocate memory space; on the other...
Read more >
How are Java objects stored in memory? - GeeksforGeeks
To allocate memory to an object, we must use new(). So the object is always allocated memory on the heap (See this for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found