Echo JS 0.11.0

<~>

xat 2593 days ago. link 5 points
IMHO it's fine to use 'in' in JS. As long as you know that it checks for the existence of a property, regardless of the value set. And also be aware that it checks properties in the prototype chain as well. If you don't want that behavior, use hasOwnProperty() instead.
jmrog 2593 days ago. link 4 points
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 thing 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).
jmrog 2592 days ago. link 1 point
Just a quick addition: one thing that would work in most cases to get around the third issue is to use a check along the lines of `if (typeof window.ontouchstart !== 'undefined')`. That may even work just as well as `'ontouchstart' in window` in practice, though whether it's better is debatable. The `in` check really checks for the existence of the key/property on the object or somewhere in the prototype chain, and, given that this check is the test that browser vendors seem to have supported for feature detection here, it's probably a little safer in this case. I fear the possibility that a vendor might some day make it so that the key, 'ontouchstart', exists on `window` when touch events are supported, but has the initial value of `undefined`, with the result that the `in` check evaluates to `true` but the `typeof` check evaluates to `false`! (And, in fact, the `typeof` check would have the same result in the author's case that the `in` check had for him in the first place: it would evaluate to `true` for him in Chrome, but `false` in Firefox. So, it wouldn't resolve the author's issue (which may result from a Firefox bug)).