One of the key changes that Gutenberg brings to the WordPress ecosystem is a heavy reliance on JavaScript. Helpfully, the WordPress team have really pushed their JavaScript framework into the present and future by leveraging the modern JavaScript stack, which is commonly referred to as ES6 in the community. It’s how we’ll refer to it as in this series too, to avoid confusion.
Let’s dig into this ES6 world a bit, as it’s ultimately going to help us understand how to structure and build a custom Gutenberg block.
Article Series:
Series Introduction
What is Gutenberg, Anyway?
A Primer with create-guten-block
Modern JavaScript Syntax (This Post)
React 101
Setting up a Custom webpack
A Custom “Card” Block
What is ES6?
ES6 is short for “EcmaScript 6” which is the 6th edition of EcmaScript. It’s official name is ES2015, which you may have also seen around. EcmaScript has since gone through many iterations, but modern JavaScript is still often referred to as ES6. As you probably guessed, the iterations have continued ES2016, ES2017 and so-on. I actually asked a question on ShopTalk show about what we could name modern JavaScript, which I the conclusion was… ES6.
I’m going to run through some key features of ES6 that are useful in the context of Gutenberg.
Functions
Functions get a heck of an update with ES6. Two changes I want to focus on are Arrow Functions and Class Methods.
Inside a class you don’t actually need to write the word function anymore in ES6. This can be confusing, so check out this example:
class Foo {
// This is your bar function
bar() {
return hello;
}
}
You’d invoke bar() like this:
const fooInstance = new Foo();
const hi = fooInstance.bar();
This is commonplace in the land of modern JavaScript, so it’s good to clear it up.
Fun fact! ES6 Classes in JavaScript aren’t really “classes” in an object-oriented programming sense—under the hood, it’s the same old prototypical inheritance JavaScript has always had. Prior to ES6, the bar() method would be defined like so: Foo.prototype.bar = function() { … }. React makes great use of ES6 classes, but it’s worth noting that ES6 classes are essentially syntactic sugar and hotly contested by some. If you’re interested in more details, checkout the MDN docs and this article on 2ality.
Right, let’s move on to arrow functions. ?
An arrow function gives us a compact syntax that is often used as a one-liner for expressions. It’s also used to maintain the value of this, as an arrow function won’t rebind this like setInterval or an event handler would usually do.
An example of an arrow function as an expression is as follows:
// Define an array of fruit objects
const fruit = [
{
name: Apple,
color: red
},
{
name: Banana,
color: yellow
},
{
name: Pear,
color: green
}
];
// Select only red fruit from that collection
const redFruit = fruit.filter(fruitItem => fruitItem.color === red);
// Output should be something like Object { name: Apple, color: red }
console.log(redFruit[0]);
As you can see above, because there was a single parameter and the function was being used as an expression, we can redact the brackets and parenthesis. This allows us to really compact our code and improve readability.
Let’s take a look at how we can use an arrow function as an event handler in our Foo class from before:
class Foo {
// This is your bar function
bar() {
let buttonInstance = document.querySelector(button);
buttonInstance.addEventListener(click, evt => {
console.log(this);
});
}
}
// Run the handler
const fooInstance = new Foo();
fooInstance.bar();
When the button is clicked, the output should be Foo { }, because this is the instance of Foo. If we were to replace that example with the following:
class Foo {
// This is your bar function
bar() {
let buttonInstance = document.querySelector(button);
buttonInstance.addEventListener(click, function(evt) {
console.log(this);
});
}
}
// Run the handler
const fooInstance = new Foo();
fooInstance.bar();
When the button is clicked, the output would be