Why you shouldn’t use ‘in’ in javascript
Mohamed Amin
146

I left this comment on the submission at EchoJS, but figured it might be worth leaving it here as well:

I don't think this post has things right.

First, Modernizr, in using `'ontouchstart' in window`, is attempting to detect only whether the browser supports touch events; it is *not* trying to detect touch devices, contrary to what the post says at one point (the comments in the Modernizr source code to which the post links seem to say this explicitly).

Second, the `in` check actually seems to be the right way (or at least the way that is now accepted) to detect this support; browser vendors that have returned `true` for this check when they don't actually support touch events have regarded that as a browser bug (Chrome example here: https://bugs.chromium.org/p/chromium/issues/detail?id=152149; Firefox example here: https://bugzilla.mozilla.org/show_bug.cgi?id=970346).

Third, and probably most importantly, the alternative proposed in the post (to just use a check like `if (window['ontouchstart'])` instead) won't work to detect support. For example, even in browsers that *do* support touch events, the check `if (window['ontouchstart'])` will still evaluate as false whenever no handler has yet been assigned to `window.ontouchstart`, and you will therefore end up with the wrong results (i.e., you'll have a case where the browser *does* support touch events, but the code will say that it doesn't support them). That's because a whole lot of things that *are* supported by the browser nevertheless start off in a falsey (`null`) state until code on the page actually sets their values. Take `window.onload`, for instance. `window.onload` is supported in every modern browser, and yet the check `if (window['onload'])` will evaluate as false on many pages, because, until someone actually sets a handler for the `onload` event, the handler is `null` (and thus falsey) by default. The fact that it's falsey doesn't mean it's not supported, so checks like that won't work for detecting support. (There are lots of other examples that you can try in your console. `window.onpopstate` is often null (so falsey), but still supported, so you can't just use `if (window['onpopstate'])` to detect support.)

By the way, `'ontouchstart' in window` is `undefined` for me in Firefox. It shouldn't be `null` unless the browser actually does support touch events, though there may be an existing Firefox bug where it is sometimes set to `null` if you have done certain things in responsive design mode before (see here: https://github.com/Modernizr/Modernizr/issues/1731).
Show your support

Clapping shows how much you appreciated Jason Rogers’s story.