Verschillen tov de vorige versies: Google Apps Script JavaScript 2020 Update - V8 Engine
JS modules zijn nog niet ondersteund.
Het gebruik van Let en Const var’s.
Let voor variabelen die tot die codeblok beperkt blijven.
Dit geeft als resultaat 2 en dan 1,omdat de 2de let de waarde van X beperkt tot de inner code block.
Const wordt gebruikt voor variabelen die niet van waarde veranderen.
Var is niet gebonden tot de code block en kan dus overschreven worden.
Dit laat je toe om een variabele vanuit een array anders samen te stellen, dan de oorspronkelijke array.
De 3dot operator zorgt voor het overnenem(samen brengen) of tussenvoegen van een array in een array
De voorgaande constructie ontbindt de bestaande array in een aantal stukken waarbij:
x = “A”
y= “B”
enz = [ “C”, “D”,”E”]
const double = x => x * 2;
Dit maakt een functie “double” die de parameter x verwacht en als antwoorde x* 2 geeft.
const arr = [1,2,3,4,5,6,7,8,9.10];
const evenArr = arr.filter(el => (el % 2 === 0));
console.log(evenArr);
Dit geeft een array terug waarbij de arr gefilterd wordt door een functie el waarbij rest van de de deling door 2 =0.
Gebruik van de class methodes en constructor, laat toe de code verder te optimaliseren
Het roepen van een methode, waarbij de string die in de return zit getoond wordt.
Het gebruik van een getter method, die een parameter uit de class kan terug geven.
Het gebruik van child classes met “extends” als instructie, waarbij de child class de methods van de hoofd class kan gebruiken.
Het gebruik van static methods in de class, waardoor je niet eerst een object moet creëren (zoals P1) maar een methode rechtstreeks kunt aanroepen in een class(vb version number van een class weergeven etc)
Het is mogelijk om de bestaande classes uit te breiden met je eigen code in V8.
In dit voorbeeld wordt de class SpreadsheetApp, die standaard bestaat, geerft door een eigen class Spreadsheet waarin de default properties (methods) worden over genomen en waar de default method getName wordt overschreven door een nieuwe functie.
Op deze wijze kan je bestaande functionaliteit uitbreiden (vb Date() class uitbreiden met .week method)
function main() {
const ss = new Spreadsheet(SpreadsheetApp.getActive());
console.log(ss._native.getName()); // MySpreadsheet
console.log(ss.getName()); // The name is MySpreadsheet
ss.moveToFolder(FOLDER_ID);
}
class Spreadsheet {
constructor(native) {
this._native = native;
// Copy native's methods to this
Object.getOwnPropertyNames(this._native).forEach(property => {
this[property] = this._native[property];
});
// Override native methods
Object.defineProperties(this, {
'getName': {
value: function() {
return `The name is ${this._native.getName()}`;
}
}
});
}
moveToFolder(folderId) {
const file = DriveApp.getFileById(this.getId());
const destination = DriveApp.getFolderById(folderId);
file.moveTo(destination);
}
}
Deze functies laten toe om met de methode next telkens een volgende waarde uit een sequentie te halen en geven als tweede parameter terug of de lijst is afgewerkt.
Stel dat je de voorgaande sequentie van 3 waardes gebruikt om telkens een nieuwe waarde te gaan halen met de methhod .next, dan zal je het volgende antwoord zien:
Waarbij je ziet dat het laatste antwoord Undefined en Done:true wordt.
Een async functie laat je toe om een .then method te gebruiken en hierop een error afhandeling te doen.
De oproep kan ook met een arrow notatie.
Dit geeft je een return waarde van 333 in de console.
Beide notaties geven hetzelfde resultaat.
Het gebruik van default parameter values laat je toe om een functie aan te roepen zonder parameters mee te geven en toch een resultaat te krijgen ipv “undifined”.
Dit zal een resultaat 1 geven, waar bij het opgeven van parameters het resultaat zal afhangen van de parameter waarde.
ES 6 Features for Google Apps Script: Template Literals
Hierbij wordt een variabel waarde direct ingevuld in een string dmv de ${var} notatie.
De uitkomst is “Your total is 12!” als de string wordt gemaakt tussen backticks.
Een string kan over meerdere lijnen verdeeld worden tussen backticks.
Globale variabelen in GAS, zijn niet eenvoudig, daar deze niet in alle gevallen beschikbaar zijn.
Een "work around" is het doorgeven van vars, maar dit vraagt dat alle functies een hoop parameters mee krijgen en terug geven, eveneens geen elegante oplossing.
Om deze problematiek aan te pakken kan je van een aantal trics gebruik maken, zoals functies in functies etc of een " getter" functie
Hierbij worden de variabelen gedeclareed buiten alle functies om.
Het probleem wat hier ontstaat is dat bij een aanroep vanuit een simpele trigger (vb onOpen()), deze globale variabele niet bestaat en dit niet werkt.
const ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/);
function doSomething1(){/*do something with ss*/}
function doSomething2(){/*do something with ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
Avoid Repeating: Use Global Variables in Google Apps Script or Not?
Het principe is als volgt:
We gebruiken een "get" binnen een object
bij de eerste vraag vanuit de functie doSomething1()van de propertie config.ss, zal de functie zelf gedelete worden en als return waarde de waarde SpreadsheetApp.openById(/*SPREADSHEET_ID*/)
terug geven
bij een een volgende vraag (vanuit de functie doSomething2()) zal de waarde terug gegeven worden.
Vermits de functie wordt aangeroepen alvorens ze gedelete wordt, zal de eerste keer de functie worden uitgevoerd en vervangen worden door de waarde.
Je bent de waarde this.ss niet kwijt bij deze eerste aanroep.
Dit is de methode om iets slechts een maal uit te voeren, de definitie van een object met getter.
const config = {
get ss() {
delete this.ss;
return (this.ss = SpreadsheetApp.openById(/*SPREADSHEET_ID*/));
},
};
function doSomething1(){/*do something with config.ss*/}
function doSomething2(){/*do something with config.ss*/}
function doItAll(){
doSomething1();
doSomething2();
}
function onOpen(){/*Adds a menu*/}
Door een object te maken, waarbij de properties worden aangevuld, kan je op deze wijze een reeks globale vars aanmaken.
De addGetter_ zorgt voor de aanmaakt van alle globale VARs die via de difinitie in een array worden doorgegeven met de naam en de functie die moet aangeroepen worden.
Vermits alles in een sequentie verloopt, dien je eerst het hoogste niveau VAR te bepalen (SS) om zo verder af te dalen in de definities.
Het oproepen van deze properties in functies gebeurt steeds door de naam van de variable g.prperty.
Hierdoor wordt het mogelijk om verschillende globale var objecten te maken.
Een alternatief is om slechts één global var space te gebruiken, zodat de extra definitie van het object voor verwijzing niet meer hoeft.
Hierdoor wordt wel alles in één object "this" gegooid...
const g = {};//global object
const addGetter_ = (name, value, obj = g) => {
Object.defineProperty(obj, name, {
enumerable: true,
configurable: true,
get() {
delete this[name];
return (this[name] = value());
},
});
return obj;
};
//MY GLOBAL VARIABLES in g
[
['ss', () => SpreadsheetApp.getActive()],
['MasterSheet', () => g.ss.getSheetByName('Sheet1')],
['MasterRangeColA1_5', () => g.MasterSheet.getRange('A1:A5')],
['MasterRangeColAValues', () => g.MasterRangeColA1_5.getValues()],
].forEach(([n, v]) => addGetter_(n, v));
const test = () => {
console.info('start');
console.log({ g });
console.info('Accessing MasterSheet');
console.log(g.MasterSheet);
console.log({ g }); //note ss is loaded as well
console.info('Accessing MasterRangeColAValues');
console.log(g.MasterRangeColAValues);
console.log({ g }); //note MasterRangeColA1_5 is loaded as well
};
const addGetter_ = (name, value, obj = this) => {
Object.defineProperty(obj, name, {
enumerable: true,
configurable: true,
get() {
delete this[name];
return (this[name] = value());
},
});
return obj;
};
//MY GLOBAL VARIABLES
[
['ss', () => SpreadsheetApp.getActive()],
['MasterSheet', () => ss.getSheetByName('Sheet1')],
['MasterRangeColA1_5', () => MasterSheet.getRange('A1:A5')],
['MasterRangeColAValues', () => MasterRangeColA1_5.getValues()],
].forEach(([n, v]) => addGetter_(n, v));
const test = () => {
console.info('start');
console.log(this);
console.info('Accessing MasterSheet');
console.log(MasterSheet);
console.log(this); //note ss is loaded as well
console.info('Accessing MasterRangeColAValues');
console.log(MasterRangeColAValues);
console.log(this); //note MasterRangeColA1_5 is loaded as well
};