JXA/Safari/ECMAScript 6

I am just waking up to something that, if I am correct, I would think I would have seen mentioned prominently here and elsewhere. (Or maybe I just missed it here.)

Am I wrong, or is it really the case that El Capitan‘s JavaScript in Safari 10 and JXA implements ECMAScript 6? (See ECMAScript 6: New Features: Overview and Comparison.) This is huge. V. 6 is a tremendous expansion of JavaScript, with a lot of changes in expressivity, power, features, and even natural object-oriented class definitions.

I'm sure others far more knowledgeable than I will jump in here, but my personal approach is to use scripts that will use features/syntax compatible with the macOS that most users have installed. While my preferred macOS is El Capitan (10.11), I try to post scripts that are compatible with Yosemite (10.10) and forward.

I have found, with few exceptions, that using JXA scripts that work with Yosemite+ do NOT impose any severe limitations on me.

This is just my personal approach. Others may differ, and choose as they see fit.

1 Like

‘JXA’ on a given macOS / OSX system is a JSContext

https://developer.apple.com/reference/javascriptcore/jscontext

running the JavaScript Core interpreter

https://developer.apple.com/reference/javascriptcore

available on that system, and provided with one extra library object in the global namespace, called Automation:

Automation
    Application
        currentApplication
    Library
    ObjC
        $
        Ref
            equals
        bindFunction
        block
        castObjectToRef
        castRefToObject
        deepUnwrap
        dict
        import
        interactWithUser
        registerSubclass
        super
        unwrap
        wrap
    ObjectSpecifier
    Path
    Progress
    delay
    getDisplayString
    initializeGlobalObject
    log

Safari 10 JS’s ES6 compliance is indeed good now:

http://kangax.github.io/compat-table/es6/

The only constraint is, of course, that of sharing Automation JS with people whose systems (Yosemite etc) are running an earlier version of JSC.

Translation back to ES5 can, however, be automated with https://babeljs.io/,

and basic translation from ES5 to ES6 can be automated with https://lebab.io

I have to agree with @JMichaelTX here. If you intend on sharing your scripts with others, then you have to write to the lowest common denominator.

If this really works seamlessly, I might consider a workflow where I write using the new Syntax Sugar, then running it through the converter before sharing a script. But to me, that opens the door for a lot of potential errors, including forgetting to do it, and not having been testing the actual code I post.

ES6 does introduce some new syntactic sugar (the destructuring assignments, fat arrow syntax for anonymous functions etc), but it would be misleading to imply that that was the main story - the key changes are more architectural – new forms of name binding, optimisation of tail recursion, new data structures etc.

(See the left hand panel at http://kangax.github.io/compat-table/es6/ )

1 Like

There are some very significant changes in some parts that go beyond syntactic sugar, unless by “syntactic sugar" you mean anything that can be translated back to ES5. I think a “normal” class structure is probably the most obvious and important change. (I have only looked into this a little — I still don't understand the difference between delegation in previous versions of JS and the new class inheritance mechanism.)

My original question was whether Safari 10 and JXA in implement ES6 in El Capitan, because I think that is a huge development and never realized it before, although the occasional mention of ES6 in this forum was gradually making its way into my awareness. I'm just surprised no-one has just come out and said that you can now use ES6 and that that opens significant new paths in JS development. Certainly not all scripts are intended for distribution to others. And if the back-translation tools really work, writing in ES6 wouldn't be much of a hinderance anyway.

Wait, I just realized what you’ve been saying. Damn Apple and their OS names.

You’ve been saying that El Capitan (10.11) now supports ES6. Holy Crap! In my mind, I kept reading that as Sierra (10.12), not El Cap, i.e. NOT the version I’m on, but the one I don’t want to upgrade to yet.

So I just checked it out, and you’re right, it certainly is supported now.

Well now, this may change my opinion. At least if not now, in the near future 3-6 months down the road.

So thanks for pointing this out! I’ve been misreading this entire thread!

I’ll repeat: Damn Apple and their OS names. :blush:

I agree ES6 is the natural medium to work in - tail recursion optimisation lends it well to functional composition for example.

On the versioning issue, the Safari 10 JSC was introduced with Sierra, and I wasn’t aware that subsequent upgrades had introduced it to El Capitan. (An El Capitan machine which I have just reached for is still running the SF9 ES5 JSC, though it may not be fully upgraded to the latest El Capitan).

In any case, I don’t think you can rely on machines running anything before Sierra being able to run ES6 JavaScript in the Automation JSContext. (As embedded in Script Editor, osascript etc)

1 Like

Safari 10.0, which I am running on El Capitan, does officially, and supposedly completely, support ES6 (see also Features - Safari for Developers), This is truly remarkable (and eliminates the only reason I could think of to ever upgrade past El Capitan). It never occurs to me to look at release notes for Apple applications, as opposed to OS-X in general.

I have been unable so far to determine the situation with JXA, although ES6 Features in JXA · dtinth/JXA-Cookbook Wiki says “From my experimentation, it turned out that JXA supports some ES6 features!”

You would certainly expect Apple to make a big deal about Safari and JXA support for ES6. That it didn't is also truly remarkable.

You would also think I would have been able to find all this by searching the web without first posting it as a question. (A simple Google search — (site:apple.com ECMAscript) brought up the information about Safari as a top hit, now that I knew what to look for.)

See ECMAScript 6 compatibility table for extreme detail on ES6 support in:

  • Compilers/polyfills
  • browsers
  • Desktop browsers
  • Mobile

Safari 10.0, which I am running on El Capitan, does officially, and supposedly completely, support ES6

Yes, you can certainly run ES6 code in a Safari 10 browser context, regardless of the OS that it's installed on (the browser context doesn't of course, include the Automation library object).

I think you may find, however, that installing Safari 10 on a pre Sierra OS doesn't in itself affect or upgrade the system copy of JSC at:

/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc

or the JSContext embedded in Script Editor and osascript.

According to that page, "JXA" has only 59% compatibility with ES6:

However, it does not say what macOS version that JXA is part of.

Where did you verify this?

IAC, can you please list the major changes/benefit to JXA scripts of using ES6?

Thanks.

According to that page, "JXA" has only 59% compatibility with ES6:

Out of date – refers only to embedded JS Contexts including an Automation object before Sierra.

Useful though, as a statement of the minimum that can be expected.

PS a simple Script Editor test might be to evaluate this snippet, which returns a value in ES6, and fails in ES5:

(() => {
    'use strict';

    return [1, 2, 3].map(x => x * 2);

})();

And you could devise a branching test of some kind.

There’s probably something subtler than this:

(function () {
    'use strict';

    try {
        eval('[1, 2, 3].map(x => x * 2)');
        return 'ES6';
    } catch (e) {
        return 'ES5';
    }
})();

Even simpler, just stick with ES5 to ensure broadest compatibility with users.
Unless, of course, there is some compelling reason for a specific use case for ES6.

Is ES6 mostly (completely?) a productivity update, or does it provide any capability that could not be done with ES5?

The major ones as I see it (depending on your programming background and preferences) are as follows. These links actually link to the first topic under the heading shown here — there is an outline on the left of the page, but no links to the headings.) I'd say that roughly the topics in first half of the outline shown are primarily syntactic sugar, but the rest contains substantial, and in some cases highly significant, additions. (It looks like at least a few features are influenced by node.js.)

(function () {
    'use strict';

    try {
        eval('[1, 2, 3].map(x => x * 2)');
        return 'ES6';
    } catch (e) {
        return 'ES5';
    }
})();

For the record, this function returns "ES5" for:

Script Editor 2.8.1 (183.1)
Safari 10.0.3 (11602.4.8.0.1)
on macOS 10.11.6

####So, macOS El Capitan 10.11.6 is NOT fully ES6 Compliant

However, it does support one ES6 that I really like:
Template literals - JavaScript | MDN

as in:

var myString = `
makes setting of multi-line
strings very easy.
And there are other features.
`

As I just posted above, macOS El Capitan 10.11.6 is NOT fully ES6 Compliant.

What would be really helpful is a table/list of ES6 features that are supported by macOS 10.11.6.

Anyone know of such list?

It’s the SF9 column here:

https://kangax.github.io/compat-table/es6/

Thanks for the reference, Rob.

I'm not sure I understand exactly what "SF 9" means

  • Does it mean JXA compliance in El Capitan 10.11.6?
  • Is that just the browser Safari Ver 9?
  • I'm running Safari 10.0.3 (11602.4.8.0.1) on macOS 10.11.6
  • But don't think the col "SF 10" applies?
  • Are the column titles defined anywhere? I couldn't find them.

IAC, to make it more readable, and to filter down the list to those functions that do work with "SF 9", I copied the table to Excel.
###Excel Table of ES6 Compatibility for SF 9, SF 10
JXA ES6 Compliance.xlsx.zip (76.3 KB)

I have set the Excel filter to show those rows where the "SF 9" col does NOT start with "0", meaning it has some compliance.

It’s the Safari 9 iteration of Apple’s JS interpreter.

That’s the JS interpreter used at system level, including osascript etc, before the Sierra iteration of OS X/macOS