2

I want to let the user define certain variables without overriding existing ones. For example, an allowed new variable:

myJSON = 123

And an invalid one:

JSON = 123

Because it overrides the existing JSON object. Before adding I could simply check if the variable is different from undefined. But I would prefer to show the user which variables are already taken too.

How can I get a comprehensive list of the browser's built-in variables?

Note that Object.keys(window) and Object.keys(document) don't contain JSON. Which other places should I check to get a comprehensive list of taken variables?

adelriosantiago
  • 7,762
  • 7
  • 38
  • 71
  • 3
    This is an interesting question. I'm wondering, though, about how this use case has manifested-- why is it a necessity to allow the user direct access to the runtime environment to declare variables at all, let alone in the global namespace? – Alexander Nied Nov 22 '20 at 05:18
  • 1
    @AlexanderNied Thanks for asking. I generalized the question on purpose to make it easier to read. I am currently facing the need let any user share everything (input, cursor position, variables, etc) to any other user who is connected to the same page. Like some sort of Google Docs for webpages. Currently `input` data is already shared but I would like to share new variables too. However built-ins should not be overwritten! If you want to know more take a look at http://boy.dog/. – adelriosantiago Nov 22 '20 at 20:54

1 Answers1

2

So, originally, I thought that the limitation was that Object.keys enumerates only an object's own properties and not inherited ones. However, trying a simple for...in loop without a hasOwnProperty check failed to yield much more than Object.keys. I also tried looping over globalThis to no avail.

A bit of further research showed that JSON is part of the family of "Standard Built-In Objects". When researching that, I came upon a similar Stack Overflow question regarding how to list all standard built-in objects in Node, and the solution was to leverage getOwnPropertyNames. This proved to be the solution-- rather than getting ≈300 results, I instead got 1000+, among which were "JSON" and "Error".

const allWindowProperties = Object.getOwnPropertyNames(window);
console.log(allWindowProperties);
console.log(allWindowProperties.includes('JSON'));
console.log(allWindowProperties.includes('Error'));

So hopefully this solves your problem. My original comment, however, is still worth exploring: How has this use case manifested? Why is it a necessity to allow the user direct access to the runtime environment to declare variables at all, let alone in the global namespace? Perhaps you have a good reason, and I do think this is an interesting question, but I wonder if perhaps we have a classic X-Y problem here.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45