Posts

Showing posts with the label esnext

ES proposal: Shared memory and atomics

The ECMAScript proposal “ Shared memory and atomics ” by Lars T. Hansen has reached stage 4 this week and will be part of ECMAScript 2017. It introduces a new constructor SharedArrayBuffer and a namespace object Atomics with helper functions. This blog post explains the details. Parallelism vs. concurrency Before we begin, let’s clarify two terms that are similar, yet distinct: “parallelism” and “concurrency”. Many definitions for them exist; I’m using them as follows: Parallelism (parallel vs. serial): execute multiple tasks simultaneously Concurrency (concurrent vs. sequential): execute several tasks during overlapping periods of time (and not one after another). Both are closely related, but not the same: Parallelism without concurrency: single instruction, multiple data (SIMD). Multiple computations happen in parallel, but only a single task (instruction) is executed at any given moment. Concurrency without parallelism: multitasking via time-sharing on a single-core CPU. However,...

Making transpiled ES modules more spec-compliant

In this blog post, you’ll learn: How a proposed “spec mode” for Babel makes transpiled ES modules more spec-compliant. That’s a crucial step in preparing for native ES modules. How ES modules and CommonJS modules will interoperate on Node.js. How far along ES module support is on browsers and Node.js. Transpiling ES modules to CommonJS via Babel At the moment, the main way to use ES modules on Node.js and browsers is to transpile them to CommonJS modules via Babel. The benefit of this approach is that integration with the CommonJS ecosystem, including npm modules, is seamless. On the flip side, the code that Babel currently generates does not comply with the ECMAScript specification. That is a problem, because code that works with Babel now, won’t work as native modules. That’s why Diogo Franco has created a pull request that adds a so-called “spec mode” to transform-es2015-modules-commonjs . Modules transpiled in this mode conform as closely to the spec as is possible without using E...

ES proposal: import() – dynamically importing ES modules

The ECMAScript proposal “ import() ” by Domenic Denicola is currently at stage 3. It enables dynamic loading of ECMAScript modules and is explained in this blog post. ECMAScript modules are static ECMAScript modules are completely static: you must specify what you import and export at compile time and can’t react to changes at runtime. That has several advantages, especially w.r.t. tooling, which are explained in “Exploring ES6”. The static structure of imports is enforced syntactically in two ways. Consider the following example: import * as someModule from './dir/someModule.js'; First, this import declaration can only appear at the top level of a module. That prevents you from importing modules inside an if statement or inside an event handler. Second, the module specifier './dir/someModule.js' is fixed; you can’t compute it at runtime (via a function call etc.). The proposal enables dynamic module imports The proposed operator for loading modules dynamically w...

Controlling access to global variables via an ES6 proxy

The following function evalCode() traces the global variables that are accessed while evaluating a piece of JavaScript code. // Simple solution const _glob = typeof global !== 'undefined' ? global : self; function evalCode(code) { const func = new Function ('proxy', `with (proxy) {${code}}`); // (A) const proxy = new Proxy(_glob, { get(target, propKey, receiver) { console.log(`GET ${String(propKey)}`); // (B) return Reflect.get(target, propKey, receiver); }, set(target, propKey, value, receiver) { // (C) console.log(`SET ${String(propKey)}=${value}`); return Reflect.set(target, propKey, value, receiver); }, }); return func(proxy); } The way this works is as follows: The with statement wrapped around the code (line A) means that every variable access that “leaves” the scope of the code becomes a ...

Pitfall: not all objects can be wrapped transparently by proxies

A proxy object can be seen as intercepting operations performed on its target object – the proxy wraps the target. The proxy’s handler object is like an observer or listener for the proxy. It specifies which operations should be intercepted by implementing corresponding methods ( get for reading a property, etc.). If the handler method for an operation is missing then that operation is not intercepted. It is simply forwarded to the target. Therefore, if the handler is the empty object, the proxy should transparently wrap the target. Alas, that doesn’t always work, as this blog post explains. Wrapping an object affects this Before we dig deeper, let’s quickly review how wrapping a target affects this : const target = { foo() { return { thisIsTarget: this === target, thisIsProxy: this === proxy, }; } }; const handler = {}; const proxy = new Proxy(target, handler); If you call target.foo() directly,...

Computing tag functions for ES6 template literals

This blog post describes what you can do with functions that return tag functions for ES6 template literals. For an introduction to template literals, tagged template literals and tag functions, consult chapter “ Template literals ” in “Exploring ES6”. Calling values via template literals The common way of calling a value in JavaScript is to append arguments in parentheses: > const value = x => x; > value(123) 123 In ES6, you can additionally call values via template literals: > value`abc` [ 'abc' ] value is now a tag function whose first parameter is an Array with template strings and whose remaining parameters are the substitutions. Functions that return tag functions If the value you call via a template literal is a function that returns a tag function then you can use arguments for the former function to parameterize the latter function. For example: In the following interaction, repeat(x) returns a tag function that repeats its template li...

Three ways of understanding Promises

This blog post covers three ways of understanding Promises . This is an example of invoking a Promise-based function asyncFunc() : function asyncFunc() { return new Promise((resolve, reject) => { setTimeout(() => resolve('DONE'), 100); }); } asyncFunc() .then(x => console.log('Result: '+x)); // Output: // Result: DONE So what is a Promise? Conceptually, invoking asyncFunc() is a blocking function call. A Promise is both a container for a value and an event emitter. Conceptually: calling a Promise-based function is blocking function asyncFunc() { return new Promise((resolve, reject) => { setTimeout(() => resolve('DONE'), 100); }); } async function main() { const x = await asyncFunc(); // (A) console.log('Result: '+x); // Same as: // asyncFunc() // .then(x => console.log('Result: '+x)); }...

Tips for using async functions (ES2017)

This blog post gives tips for using async functions. If you are unfamiliar with them, you can read chapter “ Async functions ” in “Exploring ES2016 and ES2017”. Know your Promises The foundation of async functions is Promises . That’s why understanding the latter is crucial for understanding the former. Especially when connecting old code that isn’t based on Promises with async functions, you often have no choice but to use Promises directly. For example, this is a “promisified” version of XMLHttpRequest : function httpGet(url, responseType="") { return new Promise( function (resolve, reject) { const request = new XMLHttpRequest(); request.onload = function () { if (this.status === 200) { // Success resolve(this.response); } else { // Something went wrong (404 etc.) reject(new Error(this...

ES proposal: asynchronous iteration

The ECMAScript proposal “ Asynchronous Iteration ” by Domenic Denicola is currently at stage 3. This blog post explains how it works. Asynchronous iteration With ECMAScript 6, JavaScript got built-in support for synchronously iterating over data. But what about data that is delivered asynchronously? For example, lines of text, read asynchronously from a file or an HTTP connection. This proposal brings support for that kind of data. Before we go into it, let’s first recap synchronous iteration. Synchronous iteration Synchronous iteration was introduced with ES6 and works as follows: Iterable: an object that signals that it can be iterated over, via a method whose key is Symbol.iterator . Iterator: an object returned by invoking [Symbol.iterator]() on an iterable. It wraps each iterated element in an object and returns it via its method next() – one at a time. IteratorResult: an object returned by next() . Property value contains an iterated element, property done is true after the...