Skip to main content

JavaScript...You Changed, Man


Fooling around with Bootstrap, which uses jQuery, I realized that enough has changed with the underlying JavaScript that I needed a refresher course. I came across Tokenizer by Don McCurdy, and it uses constructs that I didn't recognize.

My copy of JavaScript, the Definitive Guide, by David Flanagan, covers JS 1.5. 17 years later, we're up to ECMAScript 2018--there have been a lot of changes since I worked with Brendan Eich at Netscape. I wanted to come to an understanding of ES6 (2015) at least, and I came across JavaScript: Moving to ES2015 by Ved Antani, Simon Timms, and Narayan Prusty (Packt, 2017) as a free e-book from the Seattle Public Library.

The Tokenizer code is less than 300 lines, and much of it is comprehensible, but I ran into this:

a = a || func('arg');

This is the hip, trendy way of writing:

if (!a) a = func('arg');

Because JS doesn't evaluate the second expression if the first is true. I suppose you could also write

a = (a) ? a : func('arg');

I was more shaky with promises, and chained thens. But first, I had to decipher arrow functions. If you have an anonymous function like this:

var selected = allJobs.filter( function (job) {
return job.isSelected();
});

You can now simplify it as:

var selected = allJobs.filter( job => job.isSelected() );

It saves typing the words 'function' and 'return'. It is quite generally identifer => expression so it can be adapted to more than method calls. It reads better, I suppose. You're transforming 'job' into something else, which is exactly how it appears.

I wrote some php to query a database and return JSON, so I cribbed JavaScript code to ingest it the "modern way." I got this:

const myRequest = new Request('querydb.php?arg=' + arg);
fetch(myRequest)
    .then(response => response.json())
    .then(data => {
        ...statements like a function body...
    });


I assumed that either the Request constructor or the fetch function was blocking--that is, I assumed that execution would pause while it fetched the JSON data and then continue. JS is single-threaded, after all. No. Instead the then is executed whenever the fetch is done. The second then executes when the first then is done.

fetch(...).then(response => ...).then(data => ...)

means call the result of the fetch function 'response', apparently, and pass it as the argument to the lambda function that will return the result of the fetch function's .json() method. Because we can, we call the result of the json() method 'data'.

Not to belabor the point, but

response => response.json()

means "convert response into response's json" and hold it in mid-air until we give a name to it in the next then(). If you thought it meant "let response refer to response's json()," you'd be wrong. It makes sense (response should be immutable for this statement), but this mid-air stuff can go too far.

Comments

Popular posts from this blog

A JSON Db Product?

The last post "solved" the problem of many-to-many table joins by papering over the association table with a RESTful JSON interface. As long as we're using JSON, we might as well take advantage of multi-valued table cells. I'm naturally wondering where this leads. JSON identifiers and types and SQL identifiers and types overlap so much that their intersection is a useful subset. Camel-case fields in string, number, bool flavors. Many-to-many occurs often in the world: Students in Classes Actors in Films (musicians on recorded songs) Parts in Assemblies Customers and Products (joined by Orders) The generalized description is that a Table requires a unique identifier for each row. Tables list students, actors, films, customers, and so on.  An Association Table is has two or more foreign keys that match unique identifiers in other tables. The knowledge of how a FK maps to a specific Table is baked in--we wouldn't want a "table name" column....

JSON/MySQL Schemas

As noted previously, there is a lot of overlap between the RDBMS world and the JSON world. Identifiers JSON is defined to allow identifiers of any kind of Unicode string, encoded in UTF-8 (or UTF-16, etc.). They begin and end with double quotation marks (U+0022), so included quotation marks and '\' must be escaped as \" or \\. Control characters (ASCII 0-x1F) must be escaped as well. In practice, JSON identifiers conform to ECMAScript standards . There are some 68  reserved keywords (function, import, for, if, else, and so on) that should not be used as identifiers. Unexpected reserved words include abstract, await, debugger, delete, finally, instanceof, super, synchronized, transient, volatile, and yield. The spec makes a distinction between identifiers and IdentifierNames (specifically, array keys), but why risk it? ECMAScript allows '$' and '_' anywhere in an identifier. Length or camelCasing are not part of the spec. As for length, there seems t...