Hacker News new | past | comments | ask | show | jobs | submit login
Track down the JavaScript code responsible for polluting the global scope (mmazzarolo.com)
83 points by mmazzarolo on Feb 16, 2022 | hide | past | favorite | 15 comments



I’ve never really understood why javascript developers hate global scope and state in general.

I always make a point of having some form of app object that I can drill into and inspect from the console to see what’s going on anywhere in the application. It just speeds up development so much to be able to know what’s going on without having to set a breakpoint deep in some nest of function calls and hope you’ve been handed some form of scope that tells you what you need. It’s also handy not to have to pass a user object down through every single component in you app so that it trickles down to the corner of the navbar where you’re going to use it.

I can certainly understand if you’re publishing a library that other people are going to use, you wouldn’t want to leak out of your own box. But when it’s your own app, it just feels silly to stick in these artificial restrictions so that some junior dev who took a functional class doesn’t make snarky comments.


One thing I missed above is "But what about Testing???", since that's a common reason for building things this way.

For me, the most important aspects of a codebase are "is it Readable" and "is it Debuggable". In my mind, the problem with building in a functional style for Testability sake is that you have to trade off a lot of Debugability to get there. It's the "know what's going on" bit I wrote above. For me, it's not an acceptable tradeoff. Bug reports come in from users as "debugging requests" rather than unit tests, so I want to optimize for that sort of future work.

I actually wrote an article about this a dozen years ago [1] listing my priorities in a codebase, and I don't even think Testable made the list. I'm all for testing where it makes sense, but I'm not going to rearchitect my thing just so that testing is easier.

[1] https://www.expatsoftware.com/articles/2007/06/getting-your-...


At this point I’m not even sure if the post is talking about the same thing you’re mentioning. It’s not about “global state” in a sense of state available across the app, it’s specifically about not using the JS engine’s global object (https://developer.mozilla.org/en-US/docs/Glossary/Global_obj...) to avoid common pitfalls.


To me, there are two many reasons to avoid the global scope:

1. Like prototype extensions of JS types like "String", you're basically using a namespace that in the future might be used by a built-in API of the JavaScript engine — which would break your code.

2. You don't know for sure where your code will run in the future. A couple of years ago I worked on a migration where "standard" SPA were migrated to a micro-frontend app (where multiple SPA could be loaded on after another at the root level and each SPA would have to clean-up its own globals and listeners).

BTW I'm not against it — I DO put some stuff in the global object. If you put your entire state in a namespace like __MY_CUSTOM_SPACE__ the risk of encountering those two issues is basically 0. But I still thing there aren't many valid reasons to do so, especially with nowadays' toolings.


Your approach is very clever! I think it would be even fancier as a script hosted on a CDN a la Firebug, e.g. https://debugjs.global?var=foobar

A sort of “Drop this script tag into your app to track down that pesky variable.”


Thank you. That's a nice idea :)


Author here! In this post I'll explain a method to debug what JavaScript code is adding global variables to the window object. Hope it can help! Open to questions and feedback.


I've known about JS scope lifting for a very long time but even still I had no idea that it would lift iterators in a for-loop all the way to global scope and not just to the function scope without strict mode, that's nuts.


Well, any time you define a variable without var/let/const, I just imagine it's being defined as a property of the global state. I remember back in the day having to remind people to even use `var`.


Oh! I have some code to go fix...


I often want to do the opposite: I know that the value "HelloWorld123" ends up somewhere in a variable in the global scope. Probably in some variable, nested deep deep down in got knows what. And I want to find it. Is there a good way to go about this?


If you don't know the global names, I would probably do something like this:

1. Grab the name of all globals your JS code is creating (using https://mmazzarolo.com/blog/2022-02-14-find-what-javascript-...).

2. Inspect all of them with the technique used in the article and update the inspection logic so that it checks does a deep check of the value "HelloWorld123" as well (the value can be accessed here: https://gist.github.com/mmazzarolo/2b325f3af2bc83f56d3c921ff...)


Not all global variables get assigned to the window object. For example:

  <script>
  let foo = "bar";
  </script>
  <script>
  console.log(foo); // prints "bar"
  console.log(window.foo); // prints "undefined"
  </script>


Hey! Was this a response to another comment? In the post I'm explaining why it's happening (and it's just purposely bad code to show a global instantiation example)


this is excellent and I will definitely be using it in the future - thankyou!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: