What's new (for me) in Javascript
After finishing my echo server in Java, my mentors gave me my new assignment: write another Tic Tac Toe in NodeJS.
This is the first time since 2014 that I write an entire application in vanilla Javascript from scratch. Since then, I have been mostly touching up existing code, often jQuery, or using frameworks like EmberJS.
My limited experience with the language had been painful, so I was apprehensive of diving back into vanilla Javascript
As it turns out, I shouldn’t have been. Javascript has changed a lot, for the better. Less quirky, less verbose.
Here is a quick overview of the novelties that made it fun to write Javascript.
Class declarations
class Cat {
constructor(name) {
this.name = name;
}
}
The class
keyword was introduced by ES2015 and is not a class
implementation; it’s syntactic sugar over Javascript’s prototypal model.
let cat = new Cat('Felix');
cat.name;
// 'Felix'
Inheritance
class Player {
constructor(symbol) {
this.symbol = symbol;
}
}
class HumanPlayer extends Player {
constructor(name, symbol) {
super(symbol);
this.name = name;
}
}
let humanPlayer = new HumanPlayer('John', 'X');
console.log(humanPlayer.name);
// 'John'
console.log(humanPlayer.symbol);
// 'X'
Functions Rest Parameters
function sum(...numbers) {
return numbers.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3));
// 6
let [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]
Arrow functions
// ES5
let markedCells = cells.filter(function(cell) {
return cell.isMarked();
});
// ES6
let markedCells = cells.filter(cell => cell.isMarked());
ES6 modules
The export
statement is used to export a class, functions or primitive values from the module so they can be used by other scripts with the import
statement.
There are two kinds of exports: default exports and named exports.
Named exports
// exports a function declared earlier
export { myFunction };
// exports a constant
export const doublePi = Math.PI * 2;
Default exports (class)
// cat.js
export default class Cat {}
// other-file.js
import Cat from 'cat';
let cat = new Cat();
// ..
Default exports (function)
// math.js
export default function square(x) {
return x * x;
}
// other-file.js
import square from 'math';
console.log(square(2));
// 4
async
/ await
Promises were an improvement on callbacks. Async/await is an improvement on promises.
Specifically, async/await makes it easy to use multiple promises by allowing us to use promises synchronously. It reads nicer than promise chaining.
function fooAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('foo');
}, 2000);
});
}
function barAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('bar');
}, 2000);
});
}
async function fooBar() {
let foo = await fooAfter2Seconds();
console.log(foo);
let bar = await barAfter2Seconds();
console.log(bar);
}
fooBar();
// After 2 seconds:
// 'foo'
// After 2 more seconds:
// 'bar'
Inside the foobar
function, the second asynchronous function barAfter2Seconds
is called only once the first asynchronous function fooAfter2Seconds
has resolved.
let
and const
A variable declared with let
is limited in scope to the block, statement, or expression on which it is used. This is unlike the var
keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
Constants are block-scoped, much like variables defined using the let
statement. The value of a constant cannot change through re-assignment, and it can’t be redeclared.