JavaScript-Tutorial für Acrobat-Anwender

JavaScript, wurde ursprünglich für den Netscape Navigator entwickelt,  die die rein statische Natur von HTML‑Dokumenten um interaktive Möglichkeiten zu erweitern. Von Anfang an konnte man HTML-Formulare auswerten, Animationen erstellen, Ereignisse verarbeiten und HTML und CSS dynamisch bearbeiten.

Inzwischen wird es in vielen anderen Bereichen eingesetzt. Die Grundlagen sind einfach zu erlernen und es ist einfach anzuwenden. Es war als objektorientierte Sprache konzipiert, und die Implementierungen in den Browsern oder in Adobe-Produkten sind selbstverständlich objektorientiert: Formularelemente, Events oder Dokumente werden als Objekte repräsentiert. Viele Features von JavaScript erlauben aber auch Funktionale Programmierung, ein Paradigma, das in den letzten Jahren an Bedeutung zugenommen hat.

Nach und nach wurden die Möglichkeiten im Browser erweitert, insbesondere durch XMLHttpRequest und AJAX, dann durch Promises, und JavaScript wurde zur Default‑Skriptsprache zumindest in Webclients.

Mittlerweile wird JavaScript nicht mehr nur in Browsern eingesetzt: SAP nutzt JavaScript als Verkehrssprache für seine Datenbank SAP HANA und mit node.js kann man Webserver realisieren, um nur zwei Beispiele zu nennen. JavaScript ist neben Java eine der populärsten (und vielseitigsten und leistungsfähigsten) Sprachen überhaupt, und auch Adobe hat, neben ActionScript für andere Produkte, für Acrobat eine umfangreiche JavaScript-API:

https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/js_api_reference.pdf

JavaScript und ECMAScript

Der Markenname JavaScript legt nahe, dass eine direkte Beziehung zu Java besteht. In Wirklichkeit beschränkt sich die Beziehung auf eine deutliche Ähnlichkeit in der Syntax und darauf, dass beide Sprachen im Sprachstandard stark an C angelehnt sind.

C ist eine prozedurale Programmiersprache, die Anfang der 70er Jahre in den Bell Labs entwickelt wurde, und zwar speziell für den Zweck UNIX-Programme damit zu schreiben. Java ist eine objektorientierte Programmiersprache, die von Sun Microsystems entwickelt wurde und ab Mitte der 90er Jahre sehr schnell an Popularität gewann.

 

Tatsächlich wurde bei Netscape ab Mitte 1995 zunächst unter der Bezeichnung Mocha, dann als LiveScript sehr eilig eine Skriptsprache entwickelt, die dem Netscape Navigator einen Vorteil beim Kampf um Marktanteile verschaffen sollte.

Netscape Navigator 2.0 war der erste JavaScript-fähige Browser.

Microsoft kopierte JavaScript für den Internet Explorer, baute eigene Erweiterungen ein und nannte diese Version JScript.

Um zu verhindern, dass Microsoft die Variante mit den eigenen Erweiterungen als Standard durchsetzt, wurde Netscapes Spezifikation als ECMAScript bzw. ECMA‑262 bei der Ecma International, der Nachfolgeorganisation der ECMA (European Computer Manufacturers Association), registriert. Die Bezeichnung ECMAScript (oder ES) bezieht sich also auf die Spezifikation, JavaScript ist ein Markenname bzw. eine bestimmte Implementierung von ECMAScript, genau wie JScript oder ActionSript. Allerdings wird meistens die Bezeichnung „JavaScript“ verwendet, auch wenn „ECMAScript“ oder JScript gemeint sind.

Netscape erwarb die Rechte an JavaScript als Markenname von der Firma Sun Microsystems. Oracle erwarb mit der Übernahme von Sun Microsystems (2010) auch die Rechte an JavaScript.

Die JavaScript-Version 1.5 war 1997 die erste, die als ECMAScript 3 (ES3) registriert wurde. Der Standard wurde mehrmals überarbeitet. Bis zur Version 6 (2015) wurden die Versionen einfach durchnummeriert. Danach wurde das Jahr der Veröffentlichung des jeweiligen Standards als Versionsnummer verwendet. Der aktuelle Standard ist ECMAScript 2020.

https://www.ecma-international.org/publications/standards/Ecma-262.htm

Um die Verwirrung komplett zu machen werden die ECMAScript-Standards auch von als ISO/IEC 16262:xxxx veröffentlicht, wobei nach dem Doppelpunkt das Jahr der Veröffentlichung steht.

Die Versionsnummern von JavaScript beginnen mit 1.0 und es wurde nur der Teil rechts vom Punkt verändert: 1.3, 1.5 usw.

Die Implementierung von Adobe Acrobat entspricht der Version 1.5 bzw. ECMAScript 3, d. h. dass viele Features, um die ECMAScript seither erweitert wurde, in Adobes Implementierung für Acrobat nicht verfügbar sind.

Die JavaScript-Konsole

Die Bezeichnung „JavaScript“ ist insofern irreführend, als es keine direkte Beziehung zwischen Java und JavaScript gibt. Allerdings ist der Name insofern richtig, als es sich um eine Skriptsprache handelt.

Skriptsprachen unterscheiden sich von Programmiersprachen in dem Punkt, dass der Quelltext nicht zu einer neuen Datei kompiliert, sondern zur Laufzeit von einem Interpreter ausgeführt wird. Ein C- oder C++‑Compiler dagegen erzeugt eine ausführbare Datei, ein Java‑Compiler eine Bytecode-Datei.

Teile des JavaScript-Programms können durch einen Just‑In‑Time‑Compiler kompiliert werden, es entsteht aber niemals eine ausführbare Datei oder eine Bytecode-Datei.

 

In Acrobat ist mit der JavaScript-Konsole ein Interpreter verfügbar, mit dem man JavaScript‑Code in eine Kommandozeile eingeben und ausführen kann

Die JavaScript-Konsole ruft man auf Windows-Rechnern auf mit der Tastenkombination Strg + J, auf Macs mit + J.

Der JavaScript-Sprachstandard

Arbeiten mit JavaScript besteht darin Quelltext zu schreiben, der von einem Interpreter zur Laufzeit in Anweisungen für den Prozessor übersetzt werden kann. Das Programm besteht aus Sprachelementen wie Zuweisungen, Verzweigungen oder Iterationen, Schlüsselworten und Literalen usw. und muss exakt die Syntax-Regeln der Sprache einhalten. Außerdem sollten gewisse stilistische Konventionen beachtet werden.

Kodierung

JavaScript ist in Unicode codiert. Das heißt, dass in Bezeichnern Umlaute, und andere Buchstaben mit diakritischen Zeichen wie é, à oder ñ sowie Ligaturen wie ß oder œ, oder auch Zeichen beliebiger anderer Schriften verwendet werden können:

// bezeichner mit umlautzeichen
var länge = 5;
var breite = 6;
var höhe = 7;
var oberfläche = (länge * breite + länge * höhe + höhe * breite) * 2;
console.println(oberfläche);

// ein zeichen des griechischen alphabets als bezeichner
var α = 0.9;
console.println(α);

Laut der Versionsgeschichte von ECMAScript ist ES6 die erste Version, die in Unicode kodiert war. Die Beispiele im Tutorial wurden mit Adobe Acrobat Pro DC erstellt. Bezeichner mit ü, ä und α haben aber keine Fehler verursacht. In der Dokumentation von Adobe war ni

 

Groß- und Kleinschreibung (case sensitivity)

JavaScript unterscheidet bei Schlüsselwörtern und Bezeichnern Groß- und Kleinschreibung. while, for, null, var und dergleichen müssen exakt so geschrieben werden. While, FOR oder VAR verursachen Fehler. Desgleichen muss bei eigenen Bezeichnern auf Groß- und Kleinschreibung geachtet werden. In der Anweisung

const vat = 0.19;

ist vat ein selbst vergebener Bezeichner, und der darf an anderer Stelle nicht Vat oder VAT geschrieben werden.

Auch bei Zeichenkettenvergleichen wird Groß- und Kleinschreibung berücksichtigt:

console.println("Max" == "Max");  // true
console.println("Max" == "max");  // false

Die Strukturelemente (building blocks) von JavaScript

Building Blocks sind die semantischen Bestandteile von JavaScript-Code.

Token

Ein Token ist der kleinste Bestandteil, in den man einen Quelltext zerlegen kann. Zwischen Tokens können beliebig viele Whitespaces (Leerschrittzeichen, Tabsprünge und Zeilenumbrüche) stehen.

// token: var, xAxis, =, 72 und ;
var xAxis = 72;

// token: var, yAxis, =, 89, und;
var
yAxis
=
89
;

Beide Anweisungen sind syntaktisch richtig.

Zwischen manchen Token muss mindestens ein Leerschrittzeichen stehen, zwischen anderen nicht. Die Anweisung

varxAxis = 56;

ist zwar syntaktisch korrekt, ist aber etwas anderes als

var xAxis=56,

In der Anweisung

var zoo = ["Giraffe", "Elefant", "Vogel Strauß"];

ist das Schlüsselwort var ein Token. Der Bezeichner zoo, der Operator =, die Zeichenfolgen „Giraffe“, „Elefant“ und „Vogel Strauߓ, die eckigen Klammern [ und ] und die Kommas sind ebenfalls Token, desgleichen das Semikolon am Ende. Ob zwischen den eckigen Klammern und der Liste der Elemente ein Leerschrittzeichen, ein Zeilenumbruch oder ein Tabulator oder gar kein Whitespace steht, ist egal.

White Spaces

White Spaces (besonders Leerschrittzeichen, Zeilenumbruch und horizontaler Tabulator werden eingesetzt, um Quelltext übersichtlich zu gestalten.

function myFunction(prm) {
   if (
}

Ausdrücke (expressions)

Ein Ausdruck gibt immer einen Wert zurück:

4 < 3               // false (Boolean)
3 < 4               // true (Boolean)
1 + 3               // 4 (Numeric)
3 * 3               // 9 (Numeric)
"apfel" + "kuchen"  // apfelkuchen (String)

Mit Parenthesen kann man die Ausführungsreihenfolge beeinflussen:

3 + 4 * 6      // 72
(3 + 4) * 6    // 42

Anweisungen (statements)

Eine Anweisung (bzw. ein Statement) ist eine syntaktische Einheit mit einer Ausführungsvorschrift. In JavaScript wird ein Statement traditionell (wie in C oder C++) mit einem Semikolon abgeschlossen.

var i = 0;                     // Zuweisung
var a, b;                      // Deklaration von Variablen
a = 3; b = "schneemann";       // Initialisierung von Variablen

function getVat(net) {
  return net * 0.19;           // Return-Statement
}

var vat = getVat(200);         // Funktionsaufruf

console.println(getVat(45));   // Methodenaufruf

Ab ES6 kann man das Semikolon auch weglassen, wenn für den Interpreter klar ist, wo das Anweisungsende ist, aber aus Gründen der Lesbarkeit des Quellcodes und vielleicht besonders für Einsteiger ist es empfehlenswert ein Semikolon zu verwenden. Außerdem kann man auf der Kommandozeile mehrere Statements auf einer Zeile schreiben, wenn jedes mit einem Semikolon beendet wird. Für Adobe Acrobat gibt es diese Möglichkeit nicht.

 

Blöcke

Blöcke sind mehrere Anweisungen, die zusammengehören. Blöcke werden von geschweiften Klammern { und } begrenzt:

var = 0;
while (i < 10)
{                     // anfang des blocks
  ++i;
  console.println(i);
}                     // ende des blocks

oder auf der JavaScript-Konsole:

var i = 0; while (i < 5) {++i; console.println(i);}

Die Anweisungen ++i; und console.println(i); sind Teile einer zusammenhängenden Programmlogik und müssen durch geschweifte Klammern zu einem Block zusammengefasst werden. Die öffnende Klammer kann alleine auf einer Zeile stehen oder nicht.

Escape-Sequenzen

Einige Zeichen, die innerhalb von Zeichenketten vorkommen können, haben eine besondere Bedeutung, wenn sie maskiert sind (i. e. wenn sie direkt auf einen Rückstrich folgen):

\b      backspace                  ein Zeichen links löschen
\f      form feed                   Seitenumbruch
\n      line feed                      Zeilenumbruch
\r      carriage return          Wagenrücklauf
\t      horizontal tab             horizontaler Tabulator
\v      vertical tab                 vertikaler Tabulator

Die folgende Escapesequenz kann unterschiedliche Bedeutungen haben:

·       wenn eine der Ziffern 0 – 7 folgt, dann bedeutet das, dass ein Zahlenliteral auf der Basis 8 folgt

·       ansonsten NULL (nicht der Zahlenwert Null, sondern im Sinne von „kein Wert gesetzt“

\0      null character              NULL oder Oktalzahl

Zeichenketten müssen durch Anführungszeichen begrenzt werden. Möglich sind sowohl doppelte, als auch einfache Anführungszeichen. Wenn daher in einer Zeichenfolge mit doppelten Anführungszeichen doppelte Anführungszeichen vorkommen, müssen die inneren Anführungszeichen mit \ maskiert werden.

\"      double quote              doppeltes Anführungszeichen
\'      single quote                einfaches Anführungszeichen

Wenn innerhalb einer Zeichenkette ein Backslash vorkommt, wie bei Windows-Pfadangaben, dann muss der Backslash mit einem Backslash maskiert werden.

\\      backslash                   maskierter Backslash

kj

Kommentare

Es gibt zwei Arten von Kommentaren: einzeilige und mehrzeilige.

Die Zeichenfolge // leitet einen einzeiligen Kommentar ein.

// berechnung von kreisfläche und kreisumfang
var r = 5;                         // radius
var a = Math.PI * Math.pow(r, 2);  // fläche
var c = 2 * Math.PI * r;           // umfang

Mehrzeilige Kommentare beginnen mit /* und enden mit */

/*
   funktion zum ermitteln der länge der als Parameter
   übergebenen zeichenkette
*/
function getLength(strg) {
     return strg.length;
}

Bezeichner

Bezeichner sind Namen für Variablen, Konstanten, Objekte und Funktionen (bzw. Methoden).

var ust19 = 0.19;
var ust07 = 0.07;
var nettoBetrag = 120;
var bruttoBetrag = nettoBetrag + (nettoBetrag * ust19);

oder:

function getUst19(netto) {
  return netto * 0.19;
}

Die Zeichenfolgen ust19, ust07, nettoBetrag, bruttoBetrag, getUst19 sind Bezeichner.

Für Bezeichner gelten strikte Regeln, an die man sich unbedingt halten muss. Außerdem sollte man gewisse Konventionen beachten.

Die Regeln, die man nicht verletzen darf, betreffen die Zeichen, aus denen die Bezeichner zusammengesetzt sind:

·       Das erste Zeichen darf nur ein Buchstabe sein (klein oder groß), ein Unterstrich (_) oder ein Dollarzeichen ($).

·       Die folgenden Zeichen dürfen Buchstaben, Ziffern (0 – 9), Unterstrich oder $ sein. Andere Zeichen sind nicht zulässig.

·       Bezeichner müssen im jeweiligen Namensraum oder Scope eindeutig sein

Die Konventionen, an die man sich halten sollte:

·       Ein Bezeichner sollte möglichst sprechend sein. Bezeichner wie x21 oder bst_anz_art machen den Quelltext schwierig zu lesen.

·       Bezeichner für Klassennamen sollten mit einem Großbuchstaben beginnen, z. B. class DatabaseConnection oder class ShipmentTracker

·       Bezeichner für Variablen und Funktionen sollten mit einem Kleinbuchstaben beginnen, z. B. function getArticleNumber() oder var firstName. Die einzige Ausnahme stellen Konstruktoren dar. (Konstruktoren sind eine besondere Art von Funktionen im Zusammenhang mit dem objektorientierten Paradigma und sollten mit einem Großbuchstaben beginnen)

·       In einem Bezeichner darf kein Leerschrittzeichen oder Bindestrich vorkommen. Wenn ein Bezeichner aus mehreren Worten zusammengesetzt wird, fangen der zweite und jeder weitere Wortstamm mit einem Großbuchstaben an (CamelCase), z. B. function toString() oder var middleInitial oder class CustomerAccount. Man könnte natürlich auch schreiben to_string() oder middle_initial, oder customer_account, das ist aber in Sprachen, die in der Syntax an C angelehnt sind, nicht üblich.

·       Die Bezeichner für Konstanten schreibt man durchgängig groß und fügt bei Bedarf zwischen den Wortstämmen einen Unterstrich ein, z. B.  const CUSTOMER_REBATE.

Reservierte Wörter

Eine Reihe von Bezeichnern sind in JavaScript als Schlüsselwörter (keywords) reserviert und dürfen anderweitig nicht als Bezeichner verwendet werden:

abstract 

else 

instanceof 

super 

boolean 

enum 

int 

switch 

break 

export 

interface 

synchronized 

byte 

extends 

let 

this 

case 

false 

long 

throw 

catch 

final 

native 

throws 

char 

finally 

new 

transient 

class 

float 

null 

true 

const 

for 

package 

try 

continue 

function 

private 

typeof 

debugger 

goto 

protected 

var 

default 

if 

public 

void 

delete 

implements 

return 

volatile 

do 

import 

short 

while 

double 

in 

static 

with 

 

Einige davon sind nur reserviert, wenn sie im 'strict mode' benutzt werden. 'strict mode' gibt es zwar erst seit ES6, aber man sollte trotzdem davon absehen, sie zu benutzen. Es ist möglich, dass Adobe die Implementierung ändert, und dann hat man möglicherweise Anwendungen, die nicht mehr funktionieren, weil der Code nicht kompatibel ist.

 

Variablen und symbolische Konstanten

Variablen sind Symbole, deren Wert sich während der Programmausführung ändern kann. Symbolische Konstanten sind ebenfalls Symbole, sie können aber nur initialisiert werden, einen anderen Wert zuzuweisen ist nicht möglich.

variablen

var kontostand = 500;

function abheben(betrag) {
  kontostand -= betrag;      // subtrahiere 200 und weise das
                             // ergebnis der variablen zu
}

function einzahlen(betrag) {
  kontostand += betrag;      // addiere 200 und weise das ergebnis
                             // der variablen zu
}

abheben(200);                // subtrahiere 200 vom wert in der
                             // variablen kontostand

einzahlen(300)               // addiere 300 zum wert in der
                             // variablen kontostand

Eine Variable sollte deklariert werden, bevor sie initialisiert wird. Deklaration und Initialisierung kann in einem Statement erfolgen:

var a = 5;

oder in zwei Statements:

var b;
b = 5;

es können auch mehrere Variablen in einem Statement deklariert werden und mehrere Variablen in einem einzigen Statement initialisiert werden:

var c, d, e;
c = 3, d = false, e = "Apfelkuchen";

Deklaration von Variablen mit let ist in der JavaScript-Implementierung von Acrobat Pro DC nicht möglich.

 

JavaScript ist dynamisch typisiert, d. h. man muss nicht bei der Deklaration einer Variablen einen Datentyp vereinbaren wie in vielen anderen Sprachen, z. B. Java:

// deklaration und initialisierung von variablen in Java
int i = 1;                   // Datentyp: Integer (Ganzzahl)
double d = 0.19;             // Datentyp: double (Fließkommazahl)
boolean b = false;           // Datentyp: boolean (true oder false)
String s = "Rotkäppchen";    // Datentyp: String (Zeichenkette)
JFrame frame = new JFrame(); // Datentyp: Objekt vom Typ JFrame();

Bei jeder dieser Deklarationen wird dem Compiler gesagt, dass er Speicher reservieren soll, gleichzeitig um was für einen Datentyp es sich handelt.

Das geschieht, indem man ganz am Anfang der Anweisung das passende Schlüsselwort für den jeweiligen Datentyp verwendet: int für Ganzzahlen, double für Fließkommazahlen und den Objekttyp (JFrame) für Objekte etc. Es ist nur sehr bedingt möglich, den Datentyp einer Variablen während des Programmablaufs zu ändern.

In JavaScript ist es nicht möglich bei der Deklaration einer Variablen einen Datentyp festzulegen. Eine Variable wird in Acrobat DC immer mit dem Schlüsselwort var deklariert.

var myNumericVar = 5;
var myBooleanVar = true;
var myStringVar = "aschenputtel";
var myObjectVar = {vorname: "Hänsel", schwester: "Gretel"};

Hier werden vier Variablen deklariert und initialisiert, einmal mit einer Ganzzahl, einmal mit einem Boolean, einmal mit einer Zeichenkette und einmal mit einem Objektliteral.

Deklaration von Variablen mit let ist seit ES6 möglich. In Acrobat Pro DC gibt es diese Möglichkeit nicht.

 

Es ist auch möglich eine Variable mit einem Typ zu initialisieren und während der Programmausführung einen Wert eines anderen Typs zuzuweisen:

var a = 5;                                  // integer
a = "mean green mother from outer space";   // zeichenkette
a = {name: "Hans", age: 30};                // object

Der Gültigkeitsbereich von Variablen (variable scope)

Mit var deklarierte Variablen haben lexikalischen Scope.

JavaScript-Datentypen