4 ms·
Related: one of my favourite code golfing tricks is named access on the Window object <https://html.spec.whatwg.org/multipage/window-object.html#named-access-on
by chrismorgan 5y ago
Related: one of my favourite code golfing tricks is named access on the Window object <https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object https://html.spec.whatwg.org/multipage/window-object.html#na...>:
<div id=result></div>
<script>
document.getElementById("result").textContent = "Why do it this way—";
document.querySelector("result").textContent = "—or even this way—";
result.textContent = "—when you can do it this way?";
</script>
Edit: adding another similar test to this page, window[`test${i}`] is taking roughly twice as long as document.querySelector(`#test${i}`) in Firefox, but only half as long in Chromium—which is still a bit slower than document.getElementById(`test${i}`) in Chromium, and than window[`test${i}`] in Firefox.
- seumars 5y agoLove this trick. It should be noted that the element is added to the window object as long as the id follows the syntax of a valid javascript variable (meaning no dashes).
- chrismorgan 5y agoFalse on two counts: 1. It doesn’t need to be a valid JavaScript identifier, though if it isn’t you’ll need to use subscripting syntax to access it: > document.body.id = "like-this"; > window["like-this"] <body id="like-this"> 2. It’s not added to the window object; rather, property lookup on a window object falls back to looking up elements by ID if there is no such property: > typeof example "undefined" > document.body.id = "example"; > example <body id="example"> > example = "no longer an element"; > example "no longer an element" > delete example; true > example <body id="example">
- ducharmdev 5y agoWoah, no way. Although I could see this being abused, it's amazing that this even works.
- flomo 5y agoThis was the standard way of DOM touching in the early days, e.g. FormName.FieldName.value = "foo";
- esnard 5y agoIt has been abused to allow remote code execution in LastPass, a password manager. https://bugs.chromium.org/p/project-zero/issues/detail?id=1225 https://bugs.chromium.org/p/project-zero/issues/detail?id=12...
- JimDabell 5y agoYou could also crash Internet Explorer 6 simply by including an element with id="tags" on the page. When the user chose to print the page out, the browser would try to access window.tags, find the element instead of what it was expecting to find, and give up.
- vgallur 5y agoThere are XSS attacks abusing this behaviour named DOM Clobbering https://portswigger.net/research/dom-clobbering-strikes-back https://portswigger.net/research/dom-clobbering-strikes-back
- deleted 5y ago[deleted]
- lhorie 5y ago> code golfing tricks > window[`test${i}`] surely you must mean `eval('test'+i)` :)
- chrismorgan 5y agoWell, that was actually what I wrote first for benchmarking, but I gave up waiting for it to finish. eval is slow.
- zerocount 5y agoBug fix: document.querySelector("#result")... querySelector needs the '#' in this case.
- keeganpoppen 5y ago> one of my favourite one of? you have tricks better than this? this is so fucking spicy holy cow. how did i not know this? excuse me while i add this to all my future code for no good reason :).
- asddubs 5y agoI would seriously not recommend doing this, because it's terrible at communicating intent. Yes, it works, but someone else (if you're lucky) or you will be staring at a variable that seems to have come out of nowhere trying to figure out what's going on sooner or later. Especially if the HTML id inadvertently got changed without changing the variable in kind
- orangepanda 5y agoIt's great for quickly fiddling around in the dev console. Similarly - $0 gives access to currently selected element
- asddubs 5y agosure, for throwaway code anything goes of course
- chrismorgan 5y agoThe spec appropriately points out that this is a fragile technique. Also to avoid any doubt: if something’s called a golfing trick, you almost certainly shouldn’t use it on normal code. I confess I use this technique on every page on my website, in my carefully-golfed light/dark mode switcher. (https://chrismorgan.info/blog/dark-theme-implementation/ https://chrismorgan.info/blog/dark-theme-implementation/ has a slightly-expanded version of it, and uses a more sensible document.querySelector instead.)