V8 运行时概览

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

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

为解决此问题,Apps Script 现在由为 Chrome 和 Node.js 提供支持的 V8 运行时提供支持。您可以将现有脚本迁移到 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 Script 提供两种日志记录服务:Logger 服务console 类。这两项服务都会将日志写入同一 Stackdriver Logging 服务

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

查看执行情况

如需查看脚本的执行记录,请打开 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 和提出新功能请求。