W Apps Script i JavaScript środowisko wykonawcze lub środowisko wykonawcze zawiera silnik JavaScript, który analizuje i wykonuje kod skryptu. Środowisko wykonawcze zawiera reguły dostępu do pamięci, interakcji programu z systemem operacyjnym komputera i dozwolonej składni programu. Każda przeglądarka internetowa ma środowisko wykonawcze dla JavaScriptu.
W przeszłości Apps Script korzystał z interpretera JavaScript Rhino firmy Mozilla. Chociaż Rhino zapewniało wygodny sposób wykonywania skryptów deweloperskich w Apps Script, wiązało też Apps Script z określoną wersją JavaScriptu (ES5). Deweloperzy Apps Script nie mogą używać nowszej składni i funkcji JavaScriptu w skryptach korzystających ze środowiska wykonawczego Rhino.
Aby rozwiązać ten problem, Apps Script jest teraz obsługiwany przez środowisko wykonawcze V8, które jest używane w Chrome i Node.js. Możesz przenieść istniejące skrypty do V8, aby korzystać z nowoczesnej składni i funkcji JavaScript.
Na tej stronie opisujemy nowe funkcje, które są dostępne dzięki V8, oraz sposób włączania V8 do użycia w skryptach. Przenoszenie skryptów do V8 opisuje czynności, które należy wykonać, aby przenieść istniejące skrypty do środowiska wykonawczego V8.
Funkcje środowiska wykonawczego V8
Skrypty korzystające ze środowiska wykonawczego V8 mogą korzystać z tych funkcji:
Nowoczesna składnia ECMAScript
W skryptach opartych na środowisku wykonawczym V8 możesz używać nowoczesnej składni ECMAScript. Ta składnia obejmuje let, const i wiele innych popularnych funkcji.
Krótką listę popularnych ulepszeń składni, które możesz wprowadzić za pomocą środowiska wykonawczego V8, znajdziesz w przykładach składni V8.
Ulepszone wykrywanie funkcji
Wykrywanie funkcji Apps Script zostało ulepszone w przypadku skryptów korzystających z V8. Nowe środowisko wykonawcze rozpoznaje te formaty definicji funkcji:
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 () => {}
Wywoływanie metod obiektów z poziomu wyzwalaczy i wywołań zwrotnych
Skrypty korzystające z V8 mogą wywoływać metody obiektów i statyczne metody klas w miejscach, w których można było już wywoływać metody biblioteki. Są to między innymi:
- Wywoływanie funkcji w dodatkach do Google Workspace
- Wyzwalacze instalowane
- Elementy menu w edytorach Google Workspace
- funkcje wywołania zwrotnego użytkownika, takie jak opisana w przykładzie kodu
ScriptApp.newStateToken().
Poniższy przykład w V8 pokazuje użycie metod obiektu podczas tworzenia elementów menu w Arkuszach 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');
}
}
Wyświetl logi
Apps Script udostępnia 2 usługi rejestrowania: Logger i klasę console. Obie te usługi zapisują logi w tej samej usłudze Stackdriver Logging.
Aby wyświetlić dzienniki Logger i console, u góry edytora skryptów kliknij Dziennik wykonywania.
Wyświetlanie wykonań
Aby wyświetlić historię uruchomień skryptu, otwórz projekt Apps Script i po lewej stronie kliknij Uruchomienia .
Przykłady składni V8
Poniżej znajduje się krótka lista popularnych funkcji składniowych dostępnych w skryptach korzystających ze środowiska wykonawczego V8.
let i const
Słowa kluczowe let i const umożliwiają odpowiednio definiowanie zmiennych lokalnych o zakresie bloku i stałych o zakresie bloku.
// 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 |
Funkcje strzałkowe
Funkcje strzałkowe umożliwiają zwięzłe definiowanie funkcji w wyrażeniach.
// 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)); |
Zajęcia
Klasy umożliwiają koncepcyjne porządkowanie kodu za pomocą dziedziczenia. Klasy w V8 to przede wszystkim cukier syntaktyczny w stosunku do dziedziczenia opartego na prototypach 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) |
Przypisania destrukcyjne
Wyrażenia przypisania destrukcyjnego to szybki sposób na rozpakowanie wartości z tablic i obiektów do odrębnych zmiennych.
// 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 |
Literały szablonu
Literały szablonu to literały ciągów znaków, które umożliwiają umieszczanie wyrażeń. Pozwalają one uniknąć bardziej złożonych instrukcji łączenia ciągów znaków.
// 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}`; |
Parametry domyślne
Parametry domyślne umożliwiają określanie wartości domyślnych parametrów funkcji w deklaracji funkcji. Może to uprościć kod w treści funkcji, ponieważ eliminuje konieczność jawnego przypisywania wartości domyślnych do brakujących parametrów.
// 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!" |
Ciągi wielowierszowe
Możesz definiować ciągi wielowierszowe, używając tej samej składni co literały szablonu. Podobnie jak w przypadku literałów szablonu ta składnia pozwala uniknąć łączenia ciągów znaków i upraszcza definicje ciągów znaków.
// 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`; |
Ograniczenia środowiska wykonawczego V8
Środowisko wykonawcze Apps Script V8 nie jest standardowym środowiskiem Node.js ani przeglądarki. Może to powodować problemy ze zgodnością podczas wywoływania bibliotek innych firm lub dostosowywania przykładów kodu z innych środowisk JavaScript.
Niedostępne interfejsy API
Te standardowe interfejsy JavaScript API NIE są dostępne w środowisku wykonawczym V8 Apps Script:
- Liczniki czasu:
setTimeout,setInterval,clearTimeout,clearInterval - Strumienie:
ReadableStream,WritableStream,TextEncoder,TextDecoder - Interfejsy API sieci:
fetch,FormData,File,Blob,URL,URLSearchParams,DOMException,atob,btoa - Kryptowaluty:
crypto,SubtleCrypto - Obiekty globalne:
window,navigator,performance,process(Node.js)
Używaj tych interfejsów Apps Script API jako alternatywnych rozwiązań:
- Minutniki: używaj
Utilities.sleepdo wstrzymywania synchronicznego. Asynchroniczne timery nie są obsługiwane. - Pobieranie: użyj
UrlFetchApp.fetch(url, params), aby wysyłać żądania HTTP(S). - atob: użyj
Utilities.base64Decodedo dekodowania ciągów znaków zakodowanych w formacie Base64. - btoa: użyj
Utilities.base64Encodedo kodowania ciągów znaków w formacie Base64. - Kryptografia: używaj
Utilitiesw przypadku funkcji kryptograficznych, takich jakcomputeDigest,computeHmacSha256SignatureicomputeRsaSha256Signature.
W przypadku interfejsów API, które nie mają alternatywy w Apps Script, np. TextEncoder, możesz czasami użyć polyfillu. Polyfill to biblioteka, która replikuje funkcje interfejsu API niedostępne domyślnie w środowisku wykonawczym. Zanim użyjesz polyfillu, sprawdź, czy jest on zgodny ze środowiskiem wykonawczym V8 Apps Script.
Ograniczenia asynchroniczne
Środowisko wykonawcze V8 obsługuje składnię async i await oraz obiekt Promise.
Środowisko wykonawcze Apps Script jest jednak zasadniczo synchroniczne.
- Mikrozadania (obsługiwane): środowisko wykonawcze przetwarza kolejkę mikrozadań (w której występują wywołania zwrotne
Promise.theni rozwiązaniaawait) po wyczyszczeniu bieżącego stosu wywołań. - Makrozadania (nieobsługiwane): Apps Script nie ma standardowej pętli zdarzeń dla makrozadań. Funkcje takie jak
setTimeoutisetIntervalsą niedostępne. - Wyjątek WebAssembly: interfejs WebAssembly API jest jedyną wbudowaną funkcją, która działa w sposób nieblokujący w środowisku wykonawczym, co umożliwia stosowanie określonych asynchronicznych wzorców kompilacji (WebAssembly.instantiate).
Wszystkie operacje wejścia/wyjścia, takie jak UrlFetchApp.fetch, są blokujące. Aby uzyskać równoległe żądania sieciowe, użyj
UrlFetchApp.fetchAll.
Ograniczenia dotyczące zajęć
Środowisko wykonawcze V8 ma określone ograniczenia dotyczące nowoczesnych funkcji klas ES6+:
- Pola prywatne: prywatne pola klasy (np.
#field) nie są obsługiwane i powodują błędy analizowania. Aby uzyskać prawdziwe hermetyzowanie, rozważ użycie domknięć lubWeakMap. - Pola statyczne: bezpośrednie deklaracje pól statycznych w treści klasy (np.
static count = 0;) nie są obsługiwane. Przypisz do klasy właściwości statyczne po jej zdefiniowaniu (np.MyClass.count = 0;).
Ograniczenia modułu
- Moduły ES6: środowisko wykonawcze V8 nie obsługuje modułów ES6 (
import/export). Aby używać bibliotek, musisz skorzystać z mechanizmu bibliotek Apps Script lub połączyć kod i jego zależności w jeden plik skryptu. (Issue Tracker) - Kolejność wykonywania plików: wszystkie pliki skryptów w projekcie są wykonywane w zakresie globalnym. Najlepiej unikać kodu najwyższego poziomu z efektami ubocznymi i upewnić się, że funkcje i klasy są zdefiniowane przed użyciem w plikach. W edytorze możesz jawnie uporządkować pliki, jeśli istnieją między nimi zależności.
Włączanie środowiska wykonawczego V8
Jeśli skrypt korzysta ze środowiska wykonawczego Rhino, możesz przełączyć go na V8, wykonując te czynności:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Włącz środowisko wykonawcze Chrome V8.
Możesz też określić środowisko wykonawcze skryptu bezpośrednio, edytując plik manifestu skryptu:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Wyświetlaj plik manifestu „appsscript.json” w edytorze.
- Po lewej stronie kliknij Edytor >
appsscript.json. - W pliku manifestu
appsscript.jsonustaw poleruntimeVersionna wartośćV8. - U góry kliknij Zapisz projekt .
W artykule Przenoszenie skryptów do V8 znajdziesz inne czynności, które należy wykonać, aby skrypt działał prawidłowo w środowisku V8.
Włączanie środowiska wykonawczego Rhino
Jeśli Twój skrypt korzysta z V8 i musisz przełączyć go na oryginalne środowisko wykonawcze Rhino, wykonaj te czynności:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Odznacz pole wyboru Włącz środowisko wykonawcze Chrome 8.
Możesz też edytować plik manifestu skryptu:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Wyświetlaj plik manifestu „appsscript.json” w edytorze.
- Po lewej stronie kliknij Edytor >
appsscript.json. - W pliku manifestu
appsscript.jsonustaw poleruntimeVersionna wartośćDEPRECATED_ES5. - U góry kliknij Zapisz projekt .
Jak przeprowadzić migrację istniejących skryptów?
Przewodnik Przenoszenie skryptów do V8 zawiera opis czynności, które musisz wykonać, aby przenieść istniejący skrypt do V8. Obejmuje to włączenie środowiska wykonawczego V8 i sprawdzenie skryptu pod kątem znanych niezgodności.
Automatyczna migracja skryptów do V8
18 lutego 2020 roku Google zacznie stopniowo przenosić do V8 istniejące skrypty, które przejdą nasz automatyczny test zgodności. Po migracji skrypty, których dotyczy problem, nadal działają normalnie.
Jeśli chcesz zrezygnować z automatycznej migracji skryptu, ustaw w jego manifeście pole
runtimeVersion
na wartość DEPRECATED_ES5. W każdej chwili możesz przenieść skrypt do V8.
Jak zgłaszać błędy?
W przewodniku pomocy znajdziesz informacje o tym, jak uzyskać pomoc dotyczącą programowania na stronie Stack Overflow, wyszukiwać istniejące raporty o problemach, zgłaszać nowe błędy i przesyłać prośby o dodanie nowych funkcji.