ArangoDB 2.5 comes with an upgraded version of V8, Google’s open source JavaScript engine.
The built-in version of V8 has been upgraded from 3.29.54 to 3.31.74.1.
In addition to several already usable ES6 features (detailed in this blog, the following ES6 features are activated in ArangoDB 2.5 by default:
- iterators and generators
- template strings
- enhanced object literals
- enhanced numeric literals
- block scoping with
let
and constant variables usingconst
- additional String methods (such as
startsWith
,repeat
etc.)
The above features are available in ArangoDB 2.5, and can now be used for scripting purposes in the ArangoShell and in server-side Foxx actions inside the database.
This blog post briefly explains the features provides some quick examples for using them.
Iterators and generators
Iterator and generator support was optional in 2.4, but is turned on by default since 2.5.
For everyone who is not familiar with generators in JavaScript, here’s how they work:
Generators are special functions tagged with an asterisk (*
). Values are returned to the
caller using the yield
keyword:
1 2 3 4 |
|
Calling the function with initialize/reset the generator. Calling the next()
method on
the generator’s initial call return value produces the next sequence element. The element
is returned in a value
attribute. The done
attribute indicates whether the sequence
has come to an end:
1 2 3 4 |
|
Sequences produced by generators can also be consumed via a for...of
loop:
1 2 3 4 5 |
|
In general, every object that is iteratable can be consumed using the of
operator.
Some built-in objects provide pre-defined iterators (e.g. Map.keys()
or Map.values()
),
but you can also create iterators for your own objects:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Template strings
I know there are query string generators and such, but for the sake of the example, let’s assume you wanted to write a query string in JavaScript. You might end up with something like this:
1 2 3 4 |
|
This is hardly legible, and it is also very prone to errors.
ES6 template strings provide a way to define multi-line string literals in a much easier and simpler way. Here’s how to do it (note the backticks instead of the regular string quotes):
1 2 3 4 5 |
|
Template strings also support value substitution, so you could even write something like this, too:
1 2 3 4 5 6 7 |
|
Note that while value substitution in template strings in convenient, you still have to be careful with user-generated values. Otherwise you might be subject to value injection attacks, as you would be with every other form of improper user value handling.
Enhanced object literals
Save some time when definining objects:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
As can be seen above, enhanced object literal declarations can save some typing and reduce redundancies in the code. Unfortunately we still cannot use object key names generated from expressions:
1 2 3 |
|
Enhanced numeric literals
Numeric values can now be specified in binary or octal if required:
1 2 |
|
Block scoping
As a mostly C++ programmer, I am always puzzled about the scoping of JavaScript variables.
In the following example, variable x
does not only live inside the curly brackets block in which
it was declared, but also afterwards:
1 2 3 4 5 6 |
|
The reason is that the curly brackets around var x = 1;
are not a scope at all in traditional
JavaScript. This sucks, because variables can linger around in programs longer than necessary,
leading to unwanted side-effects.
With block-level scopes, this can be fixed. To use it, introduce variables not with the var
keyword, but with let
. let
only works in strict mode, so make sure your function or module
uses it.
Now, with block-level scoping, the above snippet looks like this:
1 2 3 4 5 6 7 |
|
And it will actually produce an error when trying to access variable x
in the return
statement.
The reason is that the life of x
was over as soon as its scope was left. The scope of variable x
is
now only the one with the let
declaration inside the curly brackets.
Someone else said “let is the new var”, and I think there’s not much to add.
Additionally, the const
keyword can be used to define a read-only variables. Trying to re-define a
constant will produce an error in strict mode (the desired behavior), and do nothing in non-strict mode.
Another reason to use the strict mode.
Additional String methods
String
objects now provide extra built-in methods:
string.startsWith(what)
string.endsWith(what)
string.includes(what)
string.repeat(count)
string.normalize(method)
string.codePointAt(position)
There is also an extra “static” method:
String.fromCodePoint(codePoint)