В Google Apps Script и JavaScript среда выполнения содержит механизм JavaScript, который анализирует и выполняет код скрипта. Среда выполнения устанавливает правила доступа к памяти, взаимодействия программы с операционной системой компьютера и допустимого синтаксиса программы. Каждый веб-браузер имеет свою среду выполнения для JavaScript.
Исторически Apps Script работал на основе интерпретатора JavaScript Rhino от Mozilla. Хотя Rhino предоставлял удобный способ выполнения скриптов для разработчиков, он также привязывал Apps Script к определенной версии JavaScript ( ES5 ). Разработчики Apps Script не могут использовать более современный синтаксис и возможности JavaScript в скриптах, использующих среду выполнения Rhino.
Для решения этой проблемы Apps Script теперь поддерживается средой выполнения V8 , которая используется в Chrome и Node.js. Переведите существующие скрипты на V8 , чтобы воспользоваться преимуществами современного синтаксиса и возможностей JavaScript.
На этой странице описаны новые возможности, предоставляемые V8, и способы включения V8 для использования в ваших скриптах. Раздел «Перенос скриптов на V8» описывает шаги по переносу существующих скриптов для использования среды выполнения V8.
Особенности среды выполнения V8
Скрипты, использующие среду выполнения V8, могут воспользоваться следующими возможностями:
Современный синтаксис ECMAScript
Используйте современный синтаксис ECMAScript в скриптах, работающих на основе среды выполнения V8. Этот синтаксис включает в себя let , const и многие другие популярные функции.
Примеры синтаксиса V8 содержат краткий список популярных улучшений синтаксиса, которые можно внести с помощью среды выполнения V8.
Среда выполнения Apps Script V8 имеет некоторые ограничения и ключевые отличия по сравнению с другими распространенными средами выполнения JavaScript. Подробнее см. раздел «Ограничения среды выполнения Apps Script 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, могут вызывать методы объектов и статические методы классов из тех мест, где уже можно вызывать методы библиотек. К таким местам относятся следующие:
- Триггеры манифеста дополнений Google Workspace
- Устанавливаемые триггеры
- Пункты меню в редакторах Google Workspace
- Функции обратного вызова пользователя, например, описанная в примере кода
ScriptApp.newStateToken().
Следующий пример на V8 демонстрирует использование методов объектов при создании пунктов меню в Google Таблицах:
function onOpen() {
const 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();
}
const 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 .
Чтобы отобразить журналы Logger и console , в верхней части редактора скриптов нажмите кнопку Execution log .
Просмотр исполнений
Чтобы просмотреть историю выполнения вашего скрипта, откройте проект Apps Script и слева нажмите Executions .
Панель «Выполнения» не предоставляет журналы с метками времени для отдельных вызовов служб Apps Script. Используйте службу console для создания соответствующих сообщений журнала. Все журналы, созданные с помощью console , отображаются на панели «Выполнения» .
Примеры синтаксиса V8
Ниже приведён краткий список популярных синтаксических функций, доступных скриптам, использующим среду выполнения V8.
let и const
Ключевые слова let и const позволяют определять локальные переменные и константы в области видимости блока соответственно.
// V8 runtime let s = "hello"; if (s === "hello") { 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 a = [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 const data = {a: 12, b: false, c: 'blue'}; const {a, c} = data; console.log(a, c); // Outputs 12 "blue" const array = [1, 2, 3]; const [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 const name = `Hi ${first} ${last}.`; const 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 const 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 const multiline = `This on the other hand, actually is a multi-line string, thanks to JavaScript ES6`; |
Ограничения времени выполнения V8
Среда выполнения Apps Script V8 не является стандартной средой Node.js или браузера. Это может привести к проблемам совместимости при использовании сторонних библиотек или адаптации примеров кода из других сред JavaScript.
Недоступные API
Следующие стандартные API JavaScript НЕ доступны в среде выполнения Apps Script V8:
- Таймеры :
setTimeout,setInterval,clearTimeout,clearInterval - Потоки :
ReadableStream,WritableStream,TextEncoder,TextDecoder - Веб-API :
fetch,FormData,File,Blob,URL,URLSearchParams,DOMException,atob,btoa - Криптография :
crypto,SubtleCrypto - Глобальные объекты :
window,navigator,performance,process(Node.js)
В качестве альтернативы можно использовать следующие API Apps Script:
- Таймеры : Используйте
Utilities.sleepдля синхронных пауз. Асинхронные таймеры не поддерживаются. - Fetch : Используйте
UrlFetchApp.fetch(url, params)для выполнения HTTP(S)-запросов. - atob : Используйте
Utilities.base64Decodeдля декодирования строк, закодированных в Base64. - btoa : Используйте
Utilities.base64Encodeдля кодирования строк в Base64. - Криптография : Используйте
Utilitiesдля криптографических функций, таких какcomputeDigest,computeHmacSha256SignatureиcomputeRsaSha256Signature.
Для API, для которых нет альтернативы в Apps Script, например, TextEncoder , иногда можно использовать полифилл. Полифил — это библиотека, которая воспроизводит функциональность API, недоступную по умолчанию в среде выполнения. Перед использованием полифилла убедитесь, что он совместим со средой выполнения V8 в Apps Script.
Ограничения асинхронности
Среда выполнения V8 поддерживает синтаксис async и await , а также объект Promise . Однако среда выполнения Apps Script по своей сути является синхронной.
- Микрозадачи (поддерживаются) : среда выполнения обрабатывает очередь микрозадач (где происходят обратные вызовы
Promise.thenи разрешенияawait) после очистки текущего стека вызовов. - Макротаски (не поддерживаются) : В Apps Script отсутствует стандартный цикл обработки событий для макротасков. Функции, такие как
setTimeoutиsetIntervalнедоступны. - Исключение WebAssembly : API WebAssembly — единственная встроенная функция, работающая в неблокирующем режиме во время выполнения, что позволяет использовать определенные шаблоны асинхронной компиляции (WebAssembly.instantiate).
Все операции ввода-вывода, такие как UrlFetchApp.fetch , являются блокирующими. Для выполнения параллельных сетевых запросов используйте UrlFetchApp.fetchAll .
Ограничения по классам
В среде выполнения V8 существуют определенные ограничения, касающиеся современных возможностей классов ES6+:
- Приватные поля : Приватные поля класса (например,
#field) не поддерживаются и вызывают ошибки синтаксического анализа. Для истинной инкапсуляции рекомендуется использовать замыкания илиWeakMap. - Статические поля : Прямое объявление статических полей в теле класса (например,
static count = 0;) не поддерживается. Присваивайте статические свойства классу после его определения (например,MyClass.count = 0;).
Ограничения модуля
- Модули ES6 : Среда выполнения V8 не поддерживает модули ES6 (
import/export). Для использования библиотек необходимо либо использовать механизм библиотек Apps Script , либо объединить ваш код и его зависимости в один скриптовый файл. ( Система отслеживания ошибок ) - Порядок выполнения файлов : Все скриптовые файлы в вашем проекте выполняются в глобальной области видимости. Лучше избегать кода верхнего уровня с побочными эффектами и убедиться, что функции и классы определены до того, как они будут использоваться в разных файлах. Явно укажите порядок выполнения файлов в редакторе, если между ними существуют зависимости.
Включить среду выполнения V8
Если скрипт использует среду выполнения Rhino, переключитесь на версию V8, выполнив следующие действия:
- Откройте проект Apps Script.
- В левой части экрана нажмите проекта» .
- Установите флажок «Включить среду выполнения Chrome V8» .
В качестве альтернативы, вы можете указать среду выполнения скрипта напрямую, отредактировав файл манифеста скрипта :
- Откройте проект Apps Script.
- В левой части экрана нажмите проекта» .
- Установите флажок «Показать файл манифеста "appsscript.json" в редакторе» .
- Слева нажмите «Редактор >
appsscript.json. - В файле манифеста
appsscript.jsonустановите полеruntimeVersionв значениеV8. - Вверху нажмите « проект» .
В разделе «Перенос скриптов на V8» описаны другие шаги, которые следует предпринять для обеспечения корректной работы скрипта при использовании V8.
Включите среду выполнения Rhino.
Если ваш скрипт использует V8 и вам необходимо переключиться на использование оригинальной среды выполнения Rhino, выполните следующие действия:
- Откройте проект Apps Script.
- В левой части экрана нажмите проекта» .
- Снимите флажок «Включить среду выполнения Chrome V8» .
В качестве альтернативы, отредактируйте манифест вашего скрипта:
- Откройте проект Apps Script.
- В левой части экрана нажмите проекта» .
- Установите флажок «Показать файл манифеста "appsscript.json" в редакторе» .
- Слева нажмите «Редактор >
appsscript.json. - В файле манифеста
appsscript.jsonустановите для поляruntimeVersionзначениеDEPRECATED_ES5. - Вверху нажмите « проект» .
Как перенести существующие скрипты?
В руководстве по миграции скриптов на V8 описаны шаги, необходимые для миграции существующего скрипта на использование V8. Это включает в себя включение среды выполнения V8 и проверку скрипта на наличие известных несовместимостей.
Автоматическая миграция скриптов на V8
Начиная с 18 февраля 2020 года Google постепенно переносит существующие скрипты, прошедшие автоматическую проверку совместимости, на V8. После миграции затронутые скрипты продолжают нормально функционировать.
Если вы хотите исключить скрипт из автоматической миграции, установите поле runtimeVersion в его манифесте в значение DEPRECATED_ES5 . В дальнейшем вы можете вручную перевести скрипт на версию V8 .
Как сообщить об ошибках?
В руководстве по поддержке объясняется, как получить помощь по программированию на Stack Overflow, искать существующие отчеты о проблемах, сообщать о новых ошибках и отправлять запросы на добавление новых функций.