V8 ランタイムの概要

Apps Script と JavaScript では、ランタイムまたはランタイム環境に、スクリプト コードを解析して実行する JavaScript エンジンが含まれています。ランタイムは、メモリへのアクセス方法、プログラムがパソコンのオペレーティング システムとやり取りする方法、有効なプログラム構文のルールを提供します。各ウェブブラウザには、JavaScript のランタイム環境があります。

これまで Apps Script には Mozilla の Rhino JavaScript インタープリタが使用されていました。Rhino は、Apps Script がデベロッパー スクリプトを実行する便利な方法を提供していましたが、Apps Script が特定の JavaScript バージョン(ES5)に関連付けられていました。Apps Script デベロッパーは、Rhino ランタイムを使用するスクリプトで、最新の JavaScript の構文と機能を使用することはできません。

この問題に対処するため、Apps Script が Chrome と Node.js を強化する V8 ランタイムでサポートされるようになりました。既存のスクリプトを V8 に移行すると、最新の JavaScript の構文と機能を利用できます。

このページでは、V8 で有効になる新機能と、V8 をスクリプトで使用できるようにする方法について説明します。V8 へのスクリプトの移行では、V8 ランタイムを使用するように既存のスクリプトを移行する手順について説明しています。

V8 ランタイムの機能

V8 ランタイムを使用するスクリプトでは、次の機能を利用できます。

最新の ECMAScript 構文

V8 ランタイムを利用するスクリプトでは、最新の ECMAScript 構文を使用できます。この構文には、letconst など、一般的な機能が多数含まれています。

V8 ランタイムを使用して行うことができる一般的な構文の改善の一覧については、V8 構文の例をご覧ください。

関数検出の改善

Apps Script 関数の検出機能は、V8 を使用するスクリプト向けに改善されています。新しいランタイムは、次の関数定義形式を認識します。

      function normalFunction() {}
      async function asyncFunction() {}
      function* generatorFunction() {}

      var varFunction = function() {}
      let letFunction = function() {}
      const constFunction = function() {}

      var namedVarFunction = function alternateNameVarFunction() {}
      let namedLetFunction = function alternateNameLetFunction() {}
      const namedConstFunction = function alternateNameConstFunction() {}

      var varAsyncFunction = async function() {}
      let letAsyncFunction = async function() {}
      const constAsyncFunction = async function() {}

      var namedVarAsyncFunction = async function alternateNameVarAsyncFunction() {}
      let namedLetAsyncFunction = async function alternateNameLetAsyncFunction() {}
      const namedConstAsyncFunction = async function alternateNameConstAsyncFunction() {}

      var varGeneratorFunction = function*() {}
      let letGeneratorFunction = function*() {}
      const constGeneratorFunction = function*() {}

      var namedVarGeneratorFunction = function* alternateNameVarGeneratorFunction() {}
      let namedLetGeneratorFunction = function* alternateNameLetGeneratorFunction() {}
      const namedConstGeneratorFunction = function* alternateNameConstGeneratorFunction() {}

      var varLambda = () => {}
      let letLambda = () => {}
      const constLambda = () => {}

      var varAsyncLambda = async () => {}
      let letAsyncLambda = async () => {}
      const constAsyncLambda = async () => {}

トリガーとコールバックからオブジェクト メソッドを呼び出す

V8 を使用するスクリプトでは、すでにライブラリ メソッドを呼び出せる場所から、オブジェクト メソッドやクラスの静的メソッドを呼び出すことができます。たとえば、次のような場所です。

次の V8 の例は、Google スプレッドシートでメニュー項目を作成するときにオブジェクト メソッドを使用する方法を示しています。

function onOpen() {
  var ui = SpreadsheetApp.getUi(); // Or DocumentApp, SlidesApp, or FormApp.
  ui.createMenu('Custom Menu')
      .addItem('First item', 'menu.item1')
      .addSeparator()
      .addSubMenu(ui.createMenu('Sub-menu')
          .addItem('Second item', 'menu.item2'))
      .addToUi();
}

var menu = {
  item1: function() {
    SpreadsheetApp.getUi().alert('You clicked: First item');
  },
  item2: function() {
    SpreadsheetApp.getUi().alert('You clicked: Second item');
  }
}

ログの表示

Apps Script には、Logger サービスconsole クラスの 2 つのロギング サービスがあります。どちらのサービスも、同じ Stackdriver Logging サービスにログを書き込みます。

Logger ログと console ログを表示するには、スクリプト エディタの上部にある [実行ログ] をクリックします。

実行を表示

スクリプトの実行履歴を表示するには、Apps Script プロジェクトを開き、左側の [実行] をクリックします。

V8 の構文の例

V8 ランタイムを使用するスクリプトで使用できる一般的な構文機能の一部を以下に示します。

letconst

let キーワードおよび const キーワードを使用すると、ブロック スコープのローカル変数とブロック スコープ定数をそれぞれ定義できます。

// V8 runtime
let s = "hello";
if (s === "hello") {
  let s = "world";
  console.log(s);  // Prints "world"
}
console.log(s);  // Prints "hello"

const N = 100;
N = 5; // Results in TypeError
      

アロー関数

アロー関数を使用すると、式内の関数を簡潔に定義できます。

// Rhino runtime
function square(x) {
  return x * x;
}

console.log(square(5));  // Outputs 25
      
// V8 runtime
const square = x => x * x;
console.log(square(5));  // Outputs 25

// Outputs [1, 4, 9]
console.log([1, 2, 3].map(x => x * x));
      

クラス

クラスは、継承によりコードを概念的に整理する手段を提供します。V8 のクラスは、JavaScript プロトタイプ ベースの継承よりも、主に糖衣構文です。

// V8 runtime
class Rectangle {
  constructor(width, height) { // class constructor
    this.width = width;
    this.height = height;
  }

  logToConsole() { // class method
    console.log(`Rectangle(width=${this.width}, height=${this.height})`);
  }
}

const r = new Rectangle(10, 20);
r.logToConsole();  // Outputs Rectangle(width=10, height=20)
      

割り当ての分解

割り当ての分解式を使用すると、配列やオブジェクトの値を個別の変数にすばやく展開できます。

// Rhino runtime
var data = {a: 12, b: false, c: 'blue'};
var a = data.a;
var c = data.c;
console.log(a, c);  // Outputs 12 "blue"

var array = [1, 2, 3];
var x = a[0];
var y = a[1];
var z = a[2];
console.log(x, y, z);  // Outputs 1 2 3
      
// V8 runtime
var data = {a: 12, b: false, c: 'blue'};
var {a, c} = data;
console.log(a, c);  // Outputs 12 "blue"


var array = [1, 2, 3];
var [x, y, z] = array;
console.log(x, y, z);  // Outputs 1 2 3


      

テンプレート リテラル

テンプレート リテラルは、式埋め込みを許可する文字列リテラルです。これにより、より複雑な文字列連結ステートメントを回避できます。

// Rhino runtime
var name =
  'Hi ' + first + ' ' + last + '.';
var url =
  'http://localhost:3000/api/messages/'
  + id;
      
// V8 runtime
var name = `Hi ${first} ${last}.`;
var url =
  `http://localhost:3000/api/messages/${id}`;


      

デフォルトのパラメータ

デフォルト パラメータを使用すると、関数宣言で関数パラメータのデフォルト値を指定できます。これにより、不足しているパラメータにデフォルト値を明示的に割り当てる必要がなくなるため、関数本体のコードを簡素化できます。

// Rhino runtime
function hello(greeting, name) {
    greeting = greeting || "hello";
    name = name || "world";
    console.log(
        greeting + " " + name + "!");
}

hello();  // Outputs "hello world!"
      
// V8 runtime
var hello =
  function(greeting="hello", name="world") {
      console.log(
        greeting + " " + name + "!");
  }

hello();  // Outputs "hello world!"

      

複数行の文字列

複数行の文字列は、テンプレート リテラルと同じ構文を使用して定義できます。テンプレート リテラルと同様に、この構文を使用すると文字列の連結を回避し、文字列の定義を簡素化できます。

// Rhino runtime
var multiline = "This string is sort of\n"
+ "like a multi-line string,\n"
+ "but it's not really one.";
      
// V8 runtime
var multiline = `This on the other hand,
actually is a multi-line string,
thanks to JavaScript ES6`;
      

V8 ランタイムを有効にする

スクリプトが Rhino ランタイムを使用している場合は、次の手順で V8 に切り替えることができます。

  1. Apps Script プロジェクトを開きます。
  2. 左側の [プロジェクトの設定] をクリックします。
  3. [Chrome V8 ランタイムを有効にする] チェックボックスをオンにします。

または、スクリプト マニフェストを編集して、スクリプト ランタイムを直接指定することもできます。

  1. Apps Script プロジェクトを開きます。
  2. 左側の [プロジェクトの設定] をクリックします。
  3. [「appsscript.json」マニフェスト ファイルをエディタで表示する] チェックボックスをオンにします。
  4. 左側のエディタ アイコン > [appsscript.json] をクリックします。
  5. appsscript.json マニフェスト ファイルで、runtimeVersion フィールドの値を V8 に設定します。
  6. 上部の [Save project] をクリックします。

V8 へのスクリプトの移行では、V8 を使用してスクリプトを正常に機能させるために行うべきその他の手順について説明しています。

Rhino ランタイムを有効にする

スクリプトで V8 を使用していて、元の Rhino ランタイムを使用するように切り替える必要がある場合は、次の手順を行います。

  1. Apps Script プロジェクトを開きます。
  2. 左側の [プロジェクトの設定] をクリックします。
  3. [Chrome V8 ランタイムを有効にする] チェックボックスをオフにします。

または、スクリプトのマニフェストを編集します。

  1. Apps Script プロジェクトを開きます。
  2. 左側の [プロジェクトの設定] をクリックします。
  3. [「appsscript.json」マニフェスト ファイルをエディタで表示する] チェックボックスをオンにします。
  4. 左側のエディタ アイコン > [appsscript.json] をクリックします。
  5. appsscript.json マニフェスト ファイルで、runtimeVersion フィールドの値を DEPRECATED_ES5 に設定します。
  6. 上部の [Save project] をクリックします。

既存のスクリプトを移行するには、どうすればよいですか?

V8 へのスクリプトの移行では、V8 を使用するために既存のスクリプトを移行する手順について説明しています。その際、V8 ランタイムを有効にし、スクリプトに既知の非互換性がないかチェックします。

スクリプトの V8 への自動移行

2020 年 2 月 18 日より、Google は自動互換性テストに合格した既存のスクリプトを V8 に段階的に移行します。影響を受けるスクリプトは、移行後も通常どおり機能します。

スクリプトで自動移行をオプトアウトする場合は、マニフェストの runtimeVersion フィールドを DEPRECATED_ES5 に設定します。その後、いつでも手動でスクリプトを V8 に移行することができます。

バグを報告するにはどうすればよいですか?

サポートガイドでは、Stack Overflow でのプログラミングに関するサポートの利用、既存の問題レポートの検索、新しいバグの報告、新機能のリクエストを行う方法について説明します。