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.