V8 运行时概览

在 Apps 脚本和 JavaScript 中,运行时运行时环境包含用于解析和执行脚本代码的 JavaScript 引擎。运行时提供了有关内存访问方式、程序如何与计算机操作系统交互以及哪种程序语法合法的规则。每个网络浏览器都有一个适用于 JavaScript 的运行时环境。

过去,Apps 脚本一直由 Mozilla 的 Rhino JavaScript 解释器提供支持。虽然 Rhino 为 Apps 脚本提供了一种便捷的方式来执行开发者脚本,但它也将 Apps 脚本与特定的 JavaScript 版本 (ES5) 绑定。Apps 脚本开发者无法在使用 Rhino 运行时的脚本中使用更现代的 JavaScript 语法和功能。

为了解决此问题,Chrome 和 Node.js 的 V8 运行时现已支持 Apps 脚本。您可以将现有脚本迁移到 V8,以利用新型 JavaScript 语法和功能。

本页介绍了 V8 启用的新功能以及如何启用 V8 以便在脚本中使用。 将脚本迁移到 V8 介绍了迁移现有脚本以使用 V8 运行时的步骤。

V8 运行时的功能

使用 V8 运行时的脚本能够利用以下功能:

新式 ECMAScript 语法

您可以在由 V8 运行时提供支持的脚本中使用新型 ECMAScript 语法。此语法包括 letconst 以及许多其他热门功能。

请参阅 V8 语法示例,查看使用 V8 运行时可以进行哪些常用语法改进的简短列表。

改进了功能检测

针对使用 V8 的脚本改进了 Apps 脚本函数检测功能。新的运行时可识别以下函数定义格式:

      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 脚本提供两种日志记录服务:Logger 服务console 类。这两项服务都会将日志写入同一 Stackdriver Logging 服务

如需显示 Loggerconsole 日志,请点击脚本编辑器顶部的 Execution log(执行日志)。

查看执行

如需查看脚本的执行历史记录,请打开 Apps 脚本项目,然后点击左侧的执行图标

V8 语法示例

下面简要列出了使用 V8 运行时的脚本可使用的常见语法功能。

letconst

借助 letconst 关键字,您可以分别定义块级范围局部变量和块级范围常量。

// 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 脚本项目。
  2. 点击左侧的项目设置
  3. 选中启用 Chrome V8 运行时复选框。

或者,您可以通过修改脚本清单文件直接指定脚本运行时:

  1. 打开 Apps 脚本项目。
  2. 点击左侧的项目设置
  3. 选中在编辑器中显示“appsscript.json”清单文件复选框。
  4. 在左侧,依次点击编辑器 > appsscript.json
  5. appsscript.json 清单文件中,将 runtimeVersion 字段设置为 V8 值。
  6. 点击顶部的保存项目

将脚本迁移到 V8 介绍了您应采取的其他步骤,以确保脚本能够在 V8 中正常运行。

启用 Rhino 运行时

如果您的脚本使用的是 V8,并且您需要将其切换为使用原始 Rhino 运行时,请执行以下操作:

  1. 打开 Apps 脚本项目。
  2. 点击左侧的项目设置
  3. 取消选中启用 Chrome V8 运行时复选框。

或者,修改您的脚本清单:

  1. 打开 Apps 脚本项目。
  2. 点击左侧的项目设置
  3. 选中在编辑器中显示“appsscript.json”清单文件复选框。
  4. 在左侧,依次点击编辑器 > appsscript.json
  5. appsscript.json 清单文件中,将 runtimeVersion 字段设置为 DEPRECATED_ES5 值。
  6. 点击顶部的保存项目

如何迁移现有脚本?

将脚本迁移到 V8 指南介绍了迁移现有脚本以使用 V8 所需执行的步骤。这涉及启用 V8 运行时并检查脚本是否存在任何已知的不兼容性。

自动将脚本迁移到 V8

从 2020 年 2 月 18 日开始,Google 将开始逐步将通过自动化兼容性测试的现有脚本迁移到 V8。迁移后,受影响的脚本会继续正常运行。

如果要为脚本停用自动迁移,请将其清单中的 runtimeVersion 字段设置为 DEPRECATED_ES5。在此之后,您可以随时选择手动将脚本迁移到 V8

如何报告 bug?

支持指南介绍了如何在 Stack Overflow 上获取编程帮助、搜索现有问题报告、提交新 bug 以及提出新的功能请求。