In fixing contrib javascript I mentioned that as a contrib maintainer or developer you could do a bit more than just run JSHint. This is because Drupal 8 will not support IE8, meaning that core and contrib are free to go crazy! The incredibly useful caniuse.com website holds extensive compatibility tables for the fancy new HTML/JS/SVG features in the works. But talking about ES5 specifically, the ECMAScript 5 compatibility table is what you’re looking for to know what you can rely on.
For core and contrib, here is a peak at what’s coming to a future near you.
Safe
By safe I mean that those are features that won’t bite you horribly. Some of them are already used in Drupal 8 core or are in a patch that’ll be committed soon enough.
"use strict"
This is actually enforced by JSHint — you know the thing that you should be
running on your JS — while we’re not relying on the advanced features of the
strict mode it is used to make sure there are no leaking variable.
I’ve seen too many strays variable in contrib and projects. To use,
put "use strict";
at the top of the file-closure.
(function ($, Drupal, drupalSettings) {
"use strict";
// Your code.
})(jQuery, Drupal, drupalSettings);
Function.prototype.bind
It is the native version of the basic usage of jQuery.proxy()
.
Before
var handler = $.proxy(callback, this);
After
var handler = callback.bind(this);
Array.prototype.forEach
Looping is a rather large topic so we’ll stick with the basics. Given the following array:
var valueList = [
'a', 'e', 'i',
'o', 'u', 'y'
];
Before
var i = 0;
var il = valueList.length;
for (; i < il; i += 1) {
}
After
function callback (value, index) {}
valueList.forEach(callback);
Object.keys
This one combined with forEach
allow you to do painless filtered for each if we take the following object:
var snacks = {
banana: 0,
chips: 1000
};
Before
for (var snack in snacks) {
if (snacks.hasOwnProperty(snack)) {
}
}
After
function eatSnacks (snack) {}
Object.keys(snacks).forEach(eatSnacks);
And that looks much better than the first example. Giving a name to your function gives you extra info on what is it the loop is doing without having to comment it too much. Also makes profiling easier since you’ll have data on the callback function.
Now you’ll probably ask why not use jQuery.each
in both cases?
or even _.each
. First it’s native so there is no need for an extra
library. I’m not talking about speed — if your bottleneck is how you do your
loops, you don’t need to read all this, otherwise go profile your DOM
manipulations. jQuery each doesn’t filter with hasOwnProperty
which means
that is some script on your page extends either Object.prototype
or
Array.prototype
— on top of breaking jQuery — you’re gonna have a bad time.
Underscore does filter properly so it’s fine using that if you have the
library on the page anyway.
I still need IE8 support
Does Drupal 8 dropping IE: 6, 7, 8 means you can’t use it in a market like china or big administrations where IE8 is still the default and supported browser?
IE8 module
The IE8 module was started to introduce IE8 compatibility back to Drupal 8 — in fact it was started to help take the decision to drop IE8. While the level of support is still undecided the goal is to allow people who develop for IE8 to be able to use Drupal 8. We’ll see what that means when that time comes. For now you can use the ie8 tag in the issue queue to help up see what’ll go wrong on IE8.
There is a lot more good stuff we can use such as localStorage
,
document.querySelector
but those are DOM-related and have nothing to do
with ES5 so expect a follow-up post on those.