You've blocked my ads, and I respect your choice.

I only ask that the next time you're looking for affordable, yet reliable hosting, that you consider Namecheap.com.

They're really excellent, and placing an order via any of these links helps me recover some of my hosting costs.

Thank you!

Namecheap.com Namecheap.com

Reasons to love ES6, part 1: Let there be class!

I hope you pardon the pun, but JavaScript is finally becoming a class act! Sure, ES6 classes are not technically much more than syntactic sugar, but if you’re anything like me, you’ve always cringed when you’ve had to begin your class definitions with function MyClass() { … A function is not very classy.

But now, thanks to the new spec, your class writing sessions can become cringe-free! Enter JavaScript classes:

Is it not pretty? And keeping your classes in separate files is now also a breeze, since as of ES6, JavaScript now has built-in import and export functionality! So let’s do something with all this fancy new stuff already!

If you haven’t read up on ES6 there might be a few things here you haven’t seen before, but not to worry, we’ll go through all of it in just a bit! Here, we define a class called Animal. It has a constructor, a prototype method, a static method, and a couple of getters and setters.

The first ES6 specific bit is the very first keyword,  let, which is the new var. The two are mostly identical, with one key difference: scope. Variables declared with var get hoisted to the top of the nearest function block, while variables declared with  let are hoisted only to the top of the enclosing block.

Consider the following:

Give it a try. After the two  fors,  i will contain the integer 10, while  j is undefined. If you’d run this code as it is,   i would be a global variable, accessible everywhere, since there’s no function block to restrict it to, but  j on the other hand only exists for the duration of the second  for, since that’s the closest enclosing block. There are many benefits to this, not the least of which is better control over who can access what and where, but a more concrete example might be a scenario, where you needed to instantiate some rather hefty classes inside a  while loop (example).

With  var you’ll need to be mindful of declaring variables inside loops, since the variable will persist even beyond the loop, and thus wont be garbage collected until the variable runs out of scope, in other words creating a memory leak. In the case of a simple counter variable holding an integer it wont matter much, but if you were working with some really heavy-duty objects, especially inside a loop, you’d eventually end up with a sluggish, if not unresponsive page. Not good. Well, with  let you’ve got one less thing to worry about, since that can’t happen. Everything declared with  let will go out of scope at the end of the loop, and your friendly garbage truck driver will promptly drive by and fetch all your used objects (not true, but close enough). Nice and tidy!

On the other side of our  let clauses is another new acquaintance,  Symbol. This is a sort of a constructor function, but you don’t use  new with it. What it constructs is a… well, symbol, which is unique to the context it was created in. Combined with  let, we have created two symbols that we will be using as object property names, that are inaccessible (not true, but close enough) outside of that class, essentially giving us something that’s not completely different from private members. I’ll demonstrate this a bit later!

Next, we have  export and default, which are part of the new language-level module system, that should at the very least reduce the amount of boilerplate code required to write modules compatible with all the current module systems. The syntax is pretty neat too, but more about that below!

Then we finally get to the class declaration itself, which not anything spectacular if you’ve ever worked with pretty much any other language that supports the object oriented paradigm, which in itself, conversely, is rather spectacular, since JavaScript has always been a bit of an oddball when it comes to writing classes. (functions as classes, eww). In the constructor we set the instance’s name and voice, but we don’t actually use the symbols we created for this specific task above. That’s because we’re not actually setting the instance’s properties directly, but we’re invoking the setters that we define just below the constructor. Setters are not an ES6 addition, but have in fact been around since IE9! For some reason this is a feature that doesn’t come up very often, at least not in the context of JavaScript.

Getters and setters are the places where we’ll put those new symbols to good use. The setters format the given strings, and save them to member variables of the current instance, which are accessed via our symbols. Since those symbols are unique, no-one without a reference to those exact same symbols can access our variables (without resorting to reflection). I chose to construct the symbols with descriptions (given as the only argument to the constructor), but descriptions do not provide a way to recreate a symbol. We could have constructed the symbols without any descriptions just as well. They are always unique.

Finally our class has two methods: one prototype method and one static method. Again, these are exactly what you’d expect, if you’ve worked with classes before. The prototype method can only be called once the class has been instantiated, while the static method is inaccessible as part of an instance. Of course even inside a method of the Animal class you could call  Animal.pet(), but not  this.pet(), unless the method you’re calling it from is also a static method (example).

That’s it for our generic animal! Let’s give it some skin and bones by extending it:

Generic animals are not much fun, unlike cats and dogs. They are of course animals too, so we’ll start by importing our  Animal class from Animal.js, here referred to as simply  'Animal' since the .js is rather implicit. To be able to import a class, you first have to export it, which is exactly what we did with the  Animal class. We also marked it as  default, and because of that we don’t need curly braces when importing it. Otherwise we’d have to change our import to  import { Animal } from 'Animal';. Not a big difference, but then again if you’re only defining one class per file (which you really should), it’s simpler to just mark the export as default.

The next bit of ES6 awesomeness is in the  constructor of the Cat class. Yes, you saw correctly, JavaScript is finally getting proper default argument values! Unfortunately there’s still no support for automatically assigning constructor arguments to instance member variables, but hey, default arguments! Much better than nothing.

Right inside the  constructor is a  super call, which means the  constructor of the parent class. When initializing a child class,  super must be called before you can assign values to member variables, or you’ll get an error.

Now we just need to actually use all these shiny new classes we’ve made:

Again, we first import the classes we need. I’m only importing  Animal here because I need it for a demonstration a few lines below; there’s no need to import it here if you’re only going to use classes extending it (though obviously those classes do need to import it in their own source files). Then we make a cat and a dog, and have them exhibit some species-typical behavior: Fidel meows and scratches, and Awa barks and finally falls asleep. We also call in Spot, but only to demonstrate that overriding default argument values works as expected.

After all that ruckus it’s time to pet the animals. The base class has a  pet() method, but since it’s static, we can only call it as long as we’re dealing with the prototype and not an actual instance of the class. Cats are smart, and they have their own  pet() method that’s non-static, and so petting Fidel works just fine. Dogs, however, are a different breed altogether, and only have the  pet() method they inherited from the parent class. Sadly it’s a static one, and Awa has to go on without any scratchings. Perhaps due to this, Awa tries to  misbehave() by trying to change her voice into something unsuitable for a dog, but thanks to our symbol access scheme she has (next to) no way of doing that. Well, she could have used the setter we provided, but she’s not that smart. Hopefully she’ll remember to provide her own methods next time.

If you’d like to play with Fidel and Awa, I’ve put all the code in a fiddle here.

That’s it for part 1, but part 2 is not far away! Hang tight!

Reasons to love ES6, part 0

So, ECMAScript 6 is by itself hardly news anymore, but not everyone is on-board yet. I’ll have to admit that I haven’t been playing with the news stuff myself for very long, but seriously, this stuff is the best thing since jQuery came out. I know, I know, jQuery is very much out-of-fashion and all that, but you have to admit that at the time it came out, it really, really made things a lot more simple. And so does ES6! I know there’s already plenty of posts about the new features, but I still feel I’d like to showcase some of them, perhaps from a bit different point of view, in an easy to approach way, if for no other reason than to give myself an excuse to tinker with all the new toys. Continue reading Reasons to love ES6, part 0