Roughly every six weeks, we create a new branch of V8 as part of our release process. Each version is branched from V8’s Git master immediately before Chrome branches for a Chrome Beta milestone. Today we’re pleased to announce our newest branch, V8 version 4.9, which will be in beta until it is released in coordination with Chrome 49 Stable. V8 4.9 is filled with all sorts of developer-facing goodies, so we’d like to give you a preview of some of the highlights in anticipation of the release in several weeks.
91% ECMAScript 2015 (ES6) support #
In V8 release 4.9 we shipped more JavaScript ES2015 features than in any other previous release, bringing us to 91% completion as measured by the Kangax compatibility table (as of January 26). V8 now supports destructuring, default parameters, Proxy objects, and the Reflect API. Release 4.9 also makes block level constructs such as class
and let
available outside of strict mode and adds support for the sticky flag on regular expressions and customizable Object.prototype.toString
output.
Destructuring #
Variable declarations, parameters, and assignments now support destructuring of objects and arrays via patterns. For example:
const o = {a: [1, 2, 3], b: {p: 4}, c: {q: 5}};
let {a: [x, y], b: {p}, c, d} = o; // x=1, y=2, p=4, c={q: 5}
[x, y] = [y, x]; // x=2, y=1
function f({a, b}) { return [a, b]; }
f({a: 4}); // [4, undefined]
Array patterns can contain rest patterns that are assigned the remainder of the array:
const [x, y, ...r] = [1, 2, 3, 4]; // x=1, y=2, r=[3,4]
Furthermore, pattern elements can be given default values, which are used in case the respective property has no match:
const {a: x, b: y = x} = {a: 4}; // x=4, y=4
// or…
const [x, y = 0, z = 0] = [1, 2]; // x=1, y=2, z=0
Destructuring can be used to make accessing data from objects and arrays more compact.
Proxies & Reflect #
After years of development, V8 now ships with a complete implementation of proxies, up-to-date with the ES2015 spec. Proxies are a powerful mechanism for virtualizing objects and functions through a set of developer-provided hooks to customize property accesses. In addition to object virtualization, proxies can be used to implement interception, add validation for property setting, simplify debugging and profiling, and unlock advanced abstractions like membranes.
To proxy an object, you must create a handler placeholder object that defines various traps and apply it to the target object which the proxy virtualizes:
const target = {};
const handler = {
get(target, name='world') {
return `Hello, ${name}!`;
}
};
const foo = new Proxy(target, handler);
foo.bar;
// → 'Hello, bar!'
The Proxy object is accompanied by the Reflect module, which defines suitable defaults for all proxy traps:
const debugMe = new Proxy({}, {
get(target, name, receiver) {
console.log(`Debug: get called for field: ${name}`);
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
console.log(`Debug: set called for field: ${name}, and value: ${value}`);
return Reflect.set(target, name, value, receiver);
}
});
debugMe.name = 'John Doe';
// Debug: set called for field: name, and value: John Doe
const title = `Mr. ${debugMe.name}`; // → 'Mr. John Doe'
// Debug: get called for field: name
For more information on the usage of Proxies and the Reflect API, see the examples section of the MDN Proxy page.
Default parameters #
In ES5 and below, optional parameters in function definitions required boilerplate code to check whether parameters were undefined:
function sublist(list, start, end) {
if (typeof start === 'undefined') start = 0;
if (typeof end === 'undefined') end = list.length;
...
}
ES2015 now allows function parameters to have default values, providing for clearer and more succinct function definitions:
function sublist(list, start = 0, end = list.length) { … }
sublist([1, 2, 3], 1);
// sublist([1, 2, 3], 1, 3)
Default parameters and destructuring can be combined, of course:
function vector([x, y, z] = []) { … }
Classes & lexical declarations in sloppy mode #
V8 has supported lexical declarations (let
, const
, block-local function
) and classes since versions 4.1 and 4.2 respectively, but so far strict mode has been required in order to use them. As of V8 release 4.9, all of these features are now enabled outside of strict mode as well, per the ES2015 spec. This makes prototyping in the DevTools Console much easier, although we encourage developers in general to upgrade to strict mode for new code.
Regular expressions #
V8 now supports the new sticky flag on regular expressions. The sticky flag toggles whether searches in strings start from the beginning of the string (normal) or from the lastIndex
property (sticky). This behavior is useful for efficiently parsing arbitrarily long input strings with many different regular expressions. To enable sticky searching, add the y
flag to a regex: (e.g. const regex = /foo/y;
).
Customizable Object.prototype.toString
output #
Using Symbol.toStringTag
, user-defined types can now return customized output when passed to Object.prototype.toString
(either directly or as a result of string coercion):
class Custom {
get [Symbol.toStringTag]() {
return 'Custom';
}
}
Object.prototype.toString.call(new Custom);
// → '[object Custom]'
String(new Custom);
// → '[object Custom]'
Improved Math.random()
#
V8 v4.9 includes an improvement in the implementation of Math.random()
. As announced last month, we switched V8’s PRNG algorithm to xorshift128+ in order to provide higher-quality pseudo-randomness.
V8 API #
Please check out our summary of API changes. This document gets regularly updated a few weeks after each major release.
Developers with an active V8 checkout can use git checkout -b 4.9 -t branch-heads/4.9
to experiment with the new features in V8 v4.9. Alternatively you can subscribe to Chrome's Beta channel and try the new features out yourself soon.