isnan

All posts tagged isnan

This afternoon I finally got around to starting to watch the videos from CascadiaJS 2013. I started with ECMAScript Regrets by David Bruant. David talked about some features in JavaScript that are broken, but cannot be changed since they would break the Internet. The key message I took away is that code authors can help avoid future regrets in the language by contributing to specs and by checking implementations before they get out of beta to make sure that they are implemented properly. I took some rough notes, and did a bit of research into anything with which I was unfamiliar:

isNaN is a mess

NaN !== NaN, so isNaN() was made to check for NaN, but it gives back strange, unexpected results. Basically, the global function isNaN() is broken, so David recommends using Number.isNan() in ES6, which returns true for NaN and false for everything else.

A polyfill can be used for earlier ES versions; no polyfill is mentioned on the MDN page for Number.isNaN, but the TC39 codex wiki on github has a Number.isNaN polyfill. There is also is-nan on npm with a compliant Number.isNaN shim.

typeof null

typeof null is "object", but should be "null". The recommendation is to use x === null. This also means that testing for object is broken, but can be worked around by testing Object(x) === x.

scope of this

this is often not what you expect. “use strict” turns use of this in functions that are not applied to something into an error, thus preventing accidental inappropriate user of this.

In ES6 arrow functions this refers to the this of the scope in which the arrow function is defined, which is much nicer.

Strict mode

I realized I had never read all that deeply into Strict mode – I know it is a good idea to use, but not the details, so I checked it out.

There is a lot of cool stuff in strict mode that makes the language more secure and less error prone. It is not worth reproducing the detail here, best just point to Strict mode on MDN. The take-home lesson is that there is no reason not to be putting 'use strict'; at the top of every module or function I write.

I was curious about strict mode in Node.js, and I found some discussion about “use strict” in node for ES6 modules. Basically it looks to be just the same as in browsers: you get strict mode if you ask for it.

stateful regexp

Using RegExp.prototype.test() twice on the same regex can give unexpected results since regular expressions in JS are stateful. Recommendation is to use String.prototype.match() instead as it will always work.

order of operations for ! and in

if (!'property' in object) will check whether false is in the object since ! has higher precedence. Looking at the JavaScript Operator Precedence Table on MDN, I see that ! has precedence 4, and in has precedence 8.

Use ESLint to detect this pattern, and replace it with if (!('property' in object)).

Bonus Section: Regrets in other web things:

CSS: box model. Fix with * { box-sizing: border-box; } (see box-sizing on MDN)

DOM: node.parentNode.removeChild(node) (or just the whole DOM).

XHR inability to do cross-origin requests by default.

localStorage

The choice to use per-origin storage for local storage means that any users or applications sharing the same domain are stepping on each other’s toes all the time. Ideally, there would be some ability to request to use a local storage specific to a page or specific path prefix. I have worked around this in one project by making a wrapper around localStorage that adds a prefix to each key, like so:

function customStorage (prefix) {
  return {
    setItem: function (key, val) {
      localStorage.setItem(prefix + key, val);
    },
    getItem: function (key) {
      return localStorage.getItem(prefix + key);
    },
    ...
  }
}

Adding a prefix based on the current page should be fairly trivial: var pageStorage = customStorage(location.pathname)