8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】ES6やES2017の構文が使えるか判定する方法

Last updated at Posted at 2018-10-06

JavaScript(ECMAScript)の実行環境によって、アロー関数(ES6~)などの新しい構文が使えたり使えなかったりします。
例えば、Internet Explorer 11ではES6以上から使える構文には対応していないので、アロー関数が利用できません。
その構文が使えるか true or false で返す関数を作ることを考えてみました。

アロー関数が使えるかどうかを返す関数

通常はあまり使われることがない Function コンストラクタを活用します。
Function コンストラクタでアロー関数を含む関数を定義できればアロー関数が使えると考えて良さそうです。

function canUseArrowFunction() {
  try {
    Function('x=>1');
    return true;
  } catch (e) {
    return false;
  }
}

ちょっと意地悪してみる

Function コンストラクタが Function = null などによって使用不能にされた場合においても、関数リテラルを使ってFunction コンストラクタを呼び出すことができました。

Function = null;
function canUseArrowFunction() {
  try {
    (function(){}).constructor('x=>1');
    return true;
  } catch (e) {
    return false;
  }
}

色々な構文で試してみる

  • canUseAsyncArrowFunction
    • ES2017から使えるようになったasync関数が使えるか
  • canUseGetSyntax
    • ES5から使えるようになったget構文が使えるか
  • canUseArrayComprehensions
    • 最新のブラウザでは使えない、配列内包という古い仕様の構文が使えるか
// async/await
function canUseAsyncArrowFunction() {
  try {
    (function(){}).constructor('async x=>1');
    return true;
  } catch (e) {
    return false;
  }
}

// アロー関数(再掲)
function canUseArrowFunction() {
  try {
    Function('x=>1');
    return true;
  } catch (e) {
    return false;
  }
}

// Objectのget構文
function canUseGetSyntax() {
  try {
    (function(){}).constructor('({get x(){}});');
    return true;
  } catch (e) {
    return false;
  }
}

// 配列内包
function canUseArrayComprehensions() {
  try {
    (function(){}).constructor('[x for each(x in [])];');
    return true;
  } catch (e) {
    return false;
  }
}

console.log('canUseAsyncArrowFunction: ' + canUseAsyncArrowFunction());
console.log('canUseArrowFunction: ' + canUseArrowFunction());
console.log('canUseGetSyntax: ' + canUseGetSyntax());
console.log('canUseArrayComprehensions: ' + canUseArrayComprehensions());

各種実行環境で実験

Google Chrome 69

chrome.png

古い構文である配列内包(canUseArrayComprehensions)は 使えないので false になっています

Internet Explorer 11

ie11.png

ES5まで対応なのでget構文(canUseGetSyntax)だけが true になっています

Node.js v10

canUseAsyncArrowFunction: true
canUseArrowFunction: true
canUseGetSyntax: true
canUseArrayComprehensions: false

Node.js v5

canUseAsyncArrowFunction: false
canUseArrowFunction: true
canUseGetSyntax: true
canUseArrayComprehensions: false

async/awaitが使えないようです(canUseAsyncArrowFunction)

Google Apps Script 1

Rhino JavaScript interpreter

gas.png 配列内包(`canUseArrayComprehensions`)が `true` になっています get構文(`canUseGetSyntax`)についても `true` になっています

V8 Runtime

gas2.png Rhino だと配列内包(`canUseArrayComprehensions`)が `true` でしたが `false` になりました。 GAS のランタイム判定に使えるかもしれません。

Adobe Extendscript Toolkit CS6

extendscript.png
ExtendscriptはES3までしか使えないらしく、すべて false でした

まとめ

Google Apps Scriptで今では非標準となった構文が使えるのが意外でした。この記事を書きながら、JavaScriptの複雑な歴史を感じてました。
(Extendscript や Google Apps Script で最新の ECMAScript の構文をトランスパイルなしで使える日は来るのでしょうか...?)

参考サイト

  1. (2020/02/06追記) 記事投稿時は Google Apps Script のランタイムとして Rhino JavaScript interpreter のみ提供されていましたが、現在では V8 も提供されるようになりました https://developers.google.com/apps-script/guides/v8-runtime 2

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?