Stronger JavaScript?

By on October 8, 2015 8:23 am

The V8 team (the JavaScript engine that powers Chrome, Opera, Node.js, MongoDB, etc…) are moving forward with an experiment in defining a stronger version of JavaScript that ensures that code being run is behaving well, and introducing run-time typing based on TypeScript’s typings. V8’s motivation is always performance, and a more stringent set of ECMAScript would obviously allow them to tune the engine to streamline performance, but are there other benefits?

We don’t need no stinking prologs!

Part of the proposal adds another prolog, "use strong";, in addition to the current "use strict";.

Many developers have some confusion around the benefits of strict mode in JavaScript, including me. "use strict"; has been around for a while and I assumed incorrectly that it helped improve performance, but modern JavaScript engines don’t actually need you to assert "use strict"; to streamline your code’s performance. Basically it just keeps you from doing things you shouldn’t be doing anyways, which should really be the job of a linting tool such as JSHint, JSCS, or ESLint. Now doing some of the things blocked by strict mode will make it impossible for the JavaScript engine to fully optimise your code, ergo, a potential benefit of using strict mode though the “should I ship with it” is an ad nauseam discussion. That said, strict mode doesn’t solve some of the most common ways of making your code unoptimisable.

Build Stronger and Smarter

Strong mode would automatically imply strict mode plus:

  • Removing support for var, instead using only let or const
  • No use before declaration
  • Accessing missing properties throws
  • Strong Objects are not extensible
  • class prototypes are frozen
  • instances are sealed
  • Arrays are non-sparse
  • arguments is eliminated
  • calling with too few arguments throws
  • No implicit coercion

These are potentially some fundamental changes to a lot of source code, but there is nothing I personally see in this list that I disagree with when you have the full benefits of ES6 and TypeScript. In many ways, using strong mode forces you to move your code towards ES6/ES2015 standards. For example, if you need a sparse array, you should be using Map instead. If you want to mutate your classes after you have declared them, you are being illogical and you should be refactoring your code instead of plastering over cracks.

The second part of strong script is run-time types based on TypeScript’s type annotations. This is incremental opt in, in that if you assert a type, the compiler will enforce it at run-time. The TypeScript team have started looking at what it might take to pass through your TypeScript code so it can be emitted in strong mode. There are some challenges in that what the V8 team propose and the semantics of TypeScript don’t quite align, but hey, we all know how to iterate, don’t we?

Yes, but what is in it for me?

Ultimately, like strict mode, strong mode just keeps you from doing silly things at run-time. Is there benefit in that? Well yes, we all solve problems the wrong way now and again, and when we do that unintentionally in fundamental pieces of our code, we can end up breaking things in strange ways that are hard to trace, have unintended consequences on other developers, or kill the performance of our code. The other thing about strong mode is that it is a contract with the compiler about the intent of our code. JavaScript is littered with flexibility and keeping all those possible options open makes it very challenging for the compiler to optimise. Specifically with strong mode, we are contracting to collapse a lot of the bad parts of pre-ES6/2015 that cause the compiler to hold open the option, just in case we do something silly.

Many of the things that strong mode is proposing are already patterns we should (or could be) following. So why have the browser enforce them at runtime? Why not just have a linting tool check our code, because having code that throws an error at runtime is never a good thing as it is usually being used by someone who didn’t write it. Well, ultimately the "use strong" prolog is a contract between the developer and the JIT compiler that says “I promise to not do anything silly” and therefore the JIT compiler can run your code through an optimized code path that performs faster, meaning better code. Consider not having to manage the arguments variable on every function call, or not being entirely sure if someone is going to declare a var on you or not. These are very tricky things for a run-time compiler to manage and tricky equals less performance.

So what is ultimately in it for the developer is better, faster, stable and more maintainable code. That can’t be a bad thing, can it?

Ok, you sold me, I want it NOW

You can experiment with both Chrome Canary, Traceur and Node.js (io.js 2.3+, Node.js 4+). In Canary, you will need to start it with --js-flags="--strong-mode", with Traceur you will need to use the strong mode branch, and with NodeJS you will need to use the --use-string flag.

Canary Chrome running in strong mode.

Canary Chrome running in strong mode.

The modern web is cool, but what do I do now?

If you’re interested in learning more about ES6, TypeScript and building strong code, we are offering a four-day online ES6 and TypeScript workshop, and we also help organizations with their approach to adopting ES6 and Typescript with our expert JavaScript support plans. If you’re not sure where to start with ES6 adoption, whether TypeScript is right for you or not or when is right to adopt other experimental web technologies, SitePen can help! Contact us for a free 30-minute consultation.