Archives

All posts by David Mason

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)

I recently read Semver in node.js and npm, which aims to shed some light on the oft misunderstood operators ~ and ^ in semver. The very short version is that:

  • ~ with just a major version will match any version with that major version.
  • ~ with a major and minor version will match any patch version of the minor version.
  • ^ will always match versions between the specified version and the next major version.

So ~1 would match 1.6.2, but ~1.4 would not; ^1 would match 1.6.2, and ^1.4 would too.

A concise overview of semver can be found at semver ftw. Plenty more detail on semver in node can be found on node-semver on github. If you look closely, you’ll notice that for the ^ and ~ operators, versions below 1.0.0 are treated differently: the first non-zero component is considered to potentially introduce breaking changes. This means that ^0.2.3 would not match version 0.3.0. Some consider this a bad idea, and I would have to agree since it complicates the system and reduces the chance that developers will use it properly. The problems with major version 0 as a special case are discussed in Kill the special pre-1.0.0 meaning for ^ & ~ and 1.0.0 is not just a number

If semver seems overly complicated, there is always slimver, which describes a simplified subset of semver. Slimver excludes prerelease and build metadata and limits version numbers to 65535, which allows easy encoding as a single numeric value for easy comparison. It also simplifies the range expressions for ~ and ^ so that their meaning is identical and versions in the 0.x.x and 0.0.x range are treated the same way as others, making it far more likely that developers will get what they are expecting when using either operator.

The theme for this week seems to have been “building a consistent web platform.” The question of whether this is a real focus in my circles for the week, or the mere overactive pattern recognition of my human brain, is moot. Here are some of the items that caught my attention:

Normalizing CSS

A colleague sent an article Introducing Normalize-OpenType.css. It looks pretty handy to me – I have never been a fan of browser inconsistencies, and anything that can bring them in line to have a consistent base on which to build is valuable in my books.

Naturally this caused me to check out the original normalize.css project, so there’s another hole in my knowledge patched up.

No more frameworks

Earlier in the week I listened to JavaScript Jabber episode 112:Refactoring JavaScript Apps Into a Framework with Brandon Hays, in which Joe Eames brought up No more JS frameworks by Joe Gregorio. The discussion got me interested, so I looked it up and started reading. In the article, Joe (the latter Joe) promotes the use of the core web platform (HTML + CSS + JS) directly, over abstracting it away behind frameworks. Joe argues that frameworks require developers to learn an extra layer of abstraction, but do not free them from dealing with the underlying platform since the abstractions are inevitably leaky. Joe advocates using web components to get reusable pieces of functionality that don’t have the compatibility issues of framework-specific components.

Libraries compose, I can keep adding more. Frameworks surround, I can have only one. @raganwald

Normalize.io

All this talk of moving away from frameworks brought to mind normalize.io, which was presented at the latest CampJS last month by Jonathan Ong. This is a really interesting project that aims to do away with a whole lot of the extra mess used in web development at the moment, such as package managers, build systems and their glut of accoutrements.

The enduring aim of the project is to support a workflow in the Normalize philosophy, allowing developers to use ES6 modules and Web Components with no need for local build tools. Normalize.io provides a suite of tools to support this workflow. The enduring tools are an intelligent file server that deals with dependencies and uses SPDY push (removing the need for file concatenation), and a caching proxy that understands semantic versioning and acts as a registry for all clients. Since the requisite browser features are not yet manifest, there is also a temporary tool, nlz, to fill in the missing functionality until browsers can take over.

“Once browsers support ES6 modules and Web Components, nlz(1) will be completely optional, and it’s main purpose will be dependency inspection”

Later in the week I re-listened to the NodeUp 65: A CampJS Show, in which Jonathan discusses some of the philosophy behind Normalize.

Web Components

Web components require 4 different pieces of browser functionality: templates, custom elements, shadow DOM and imports, according to today’s draft of Introduction to Web Components by W3C. It looks like none of these parts are yet fully endorsed by W3C, according to Web Components Current Status | W3C. The various stages of the endorsement process are shown in the W3C Process Document, 7.4 Advancing a Technical Report to Recommendation, but it is a little dry and does not exactly match the terminology on the status page; suffice it to say that in the present one does not simply use web components.

So how does one use web components without browser support? One uses polyfills. Joe Gregorio’s “No more frameworks” article mentions several polyfills to look into: Polymer, X-Tag and Bosonic.

Polymer

In keeping with the theme, while I was getting ready for work on Thursday morning I saw a tweet by Domenic Denicola linking to the Google IO live stream. I managed to catch part of a couple of web component talks: Polymer and Web Components change everything you know about Web development and Polymer and the Web Components revolution.

According to Addy Osmani in the Componentize the Web video, Polymer provides a convenient and opinionated layer on top of vanilla web components. This strays a little from the theme of filling in the inconsistencies of the web platform to work with standard technologies, since it adds data binding, event handlers and touch gestures on top of standard web components. My instinct is concern, but I get the impression that the additions can be safely ignored, so concern is probably an overreaction.

Codeacademy

  • Getting Started with Programming: 79%

Additional references:

  • Window.confirmWindow.confirm(message) shows a modal dialog with the message and OK and Cancel buttons. Returns a boolean depending what the user clicks.
  • Window.promptWindow.prompt(message, [default]) shows a prompt with the message that takes text input, with default text in the text box.
  • String

Console.log

Console.log | MDN

The simplest form of console.log takes a single object or string, but it can do a lot more:

  • If given more than 1 object, it will convert them all to strings, concatenate the strings, and print the result.
  • If given a string with substitution strings, it will replace the substitutions with the subsequent arguments.

Details about substitution strings are at Console: Outputting text to the console. It notes the following substitutions:

  • %o – hyperlink to JS object, clicking opens inspector
  • %d or %i – display an integer
  • %s – display a string
  • %f – display floating point value
  • %c – apply CSS styles. The string argument is treated as a set of CSS properties to apply. I found that specifying an empty string for a subsequent %c argument can reset the style to the default.

String.prototype.substring/slice

substring() has some undesirable behaviour, so it is far more common to see slice() used in practice. Basically, substring() does odd things when you give it negative numbers and in a few other cases. There is a nice overview in an answer to “What is the difference between String.slice and String.substring?” on StackOverflow.

I was browsing through Node.js® Reactions and came across Setting highWaterMark way too low: (trigger warning: someone does something silly and looks like they got a bit bruised in the head/knees/shins areas).

I found it immediately hilarious, then realized there was something called highWaterMark of which I was utterly ignorant! Seeking enlightenment, I set out into the open Internet. I did not have far to search, and soon found myself alighting gently on A New Streaming API for Node v0.10, and was instantly swept up in reading. I had not read long when my eyes fell upon a most wonderful sentiment:

“Being better than the next guy isn’t enough; we have to be the best imaginable.”

I had to stop, smile, and let that sink in for a while; highWaterMark all but forgotten*. This is a world I am happy to be a part of.


* I did later find highWaterMark; it is an option for streams that sets the maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.

In git, it is possible in the default configuration for anyone with commit permission to really mess things up. Someone can do a force push and wipe out everyone else’s commits.

Stop all force pushes

The bare authoritative repository can be configured to deny non-fast-forward commits such as this even when forced. An overview of this is in Git Configuration in the git book. The main settings are:

git config --system receive.denyNonFastForwards true

git config --system receive.denyDeletes true

Note that --system here will write to the /etc/gitconfig file.

Stop some force pushes

For individual branches, there is a pre-receive hook available here on Github.

I have also heard that it is possible to prevent specific users from force pushing using a pre-receive hook on the server.

Note that it is not possible to add the above on Github – the workaround is to let only a limited number of people commit, and have everyone else use pull requests.

Maybe stop some force pushes

Another option is to add a pre-push hook to run on the client, which can be used for projects on Github. This is not strictly enforceable, since a user could remove it and still do a forced push, but it can prevent accidental pushing to master, and would be a decent safety net for people new to git to make sure they can’t accidentally break something too much. Some good-looking instructions for setting it up are in the blog post Do not allow force push to master.

Fast-Forward Only Pull Requests on GitHub

Just email GitHub and ask for them, according to @domenic:

Today I made a little quine in JavaScript – someone mentioned quines and I realized I had never written one, so I wrote one. A quine is a program that can output its own source code (without taking any input).

My first attempt was a bit bloated, but got the job done:

var program = "var f=function f(){return 'var f='+f+';f(f)'; };f(f)"

I can verify that it works by evaluating the program and comparing the evaluated output to the original program:

program === eval(program)

I stripped it down a bit to end up with something I’m happier with, by making the function non-anonymous so that I could refer to it without having to bind it to a variable. Once that was done, I could make it an IIFE rather than adding a separate statement to run the function:

var program = (function f(){return '('+f+')()'; })()