| Die Funktion eval ermöglicht es, Javascript-Befehle variabel zu programmieren. Dazu werden an Stelle der Variablen, Funktionen, Objekte und Methoden deren Namen verwendet. |
Alle modernen Programmiersprachen bieten die Funktion eval oder
ein Äquivalent. Diese Funktion ist wenig bekannt, erlaubt jedoch in speziellen Fällen eine sehr elegante "Programmierung des Programms". |
Javascript
|
ECMAScript für HTML und XML |
| eval | Syntax |
| Variablen-Namen | Befehle auf verschiedene Variable anwenden |
| Objekt-Namen | Befehle für verschiedene Objekte, Methoden, Eigenschaften anwenden |
| Funktions-Namen | Verschiedene Funktionen anwenden |
| JSON | Zuweisung empfangener Daten an Arrays oder Objekte |
| DOM | Nach Möglichkeit besser das Document Object Model verwenden |
| Verwandte Themen | eval in PHP |
Programmierung von Variablen-Namen |
|
|
Mit eval ist es möglich, die Namen
von Variablen, Arrays, Objekten ... zu programmieren. Die Demo-Funktion trace zeigt den momentanen Wert einer beliebigen Variablen an. Der Name der gewünschten Variablen wird als String übergeben. Im Anwendungs-Beispiel wird mit Funktion trace verfolgt, wie sich der Wert von Variablen (hier x und y ) im Laufe des Programms ändert. |
Anwendung auf beliebige Variable:
function trace(vn) {
alert(vn+"="+eval(vn));
}
// Anwendung:
var x=123; var y=0;trace("x"); trace("y"); for(i=0;i<5;i++) {
x++; y=2*x;
}trace("x"); trace("y"); |
| Ohne eval könnte die Funktion nur eine bestimmte Variable anzeigen, mit eval jedoch jede beliebige Variable. | Vorsicht: In dieser einfachen Version kann trace nur globale Variable verfolgen (d.h. keine Variablen von Unterprogrammen) ! |
Programmierung von Objekt-Namen, -Methoden, -Eigenschaften |
|
Namen von ObjektenDas gezeigte <form> Element enthält ungewöhnlich viele Eingabe-Felder. Das trifft u.a. dann zu, wenn eine Webseite so ähnlich wie ein Kalkulations-Programm funktionieren soll.Ein Sudoku enthält z.B. 9*9=81 Eingabe-Felder. Ziel: Nach jeder Änderung soll der aktuelle Wert aller 81 Felder in einem Javascript-Programm gelesen werden. |
<form name="f1">
<input type="text" name="feld1">
</form>
<input type="text" name="feld2"> <!-- ... -->
<input type="text" name="feld81">
|
|
●
Ohne eval muss der Werte jedes einzelnen Felds mit einem eigenen
Befehl gelesen werden. (Die anschließende Verarbeitung ist zur Vereinfachung weggelassen). ● Viele ähnliche Programmzeilen sind normalerweise ein sicheres Indiz für die Auslagerung in ein Unterprogramm. An Stelle vieler ähnlicher Befehle wird ein Unterprogramm mehrfach ausgeführt. ● Wenn jedoch nicht die Daten sondern (wie hier) die Namen von Variablen oder Objekten variabel sind, ist das nicht möglich. ● eval bietet eine elegante Möglichkeit, dieses Problem zu lösen. Das Beispiel zeigt, wie die Namen (feld1, feld2, ..) als Text formuliert, in einen Befehlstext eingebaut und an eval zur Ausführung übergeben werden. |
Ohne eval:
w = document.f1.feld1.value; w = document.f1.feld2.value; // ..weitere 78 Zeilen
w = document.f1.feld81.value;
Mit eval:
for(i=1;i<=81;i++) {
t = "w=document.f1.";
}
t+="feld"+i+".value;"; eval(t); |
| Diese Methode bringt umso mehr Vorteile, je mehr gleichartige oder ähnliche Objekte zu bearbeiten sind. | ● Alternative: Versehen sie jedes zu verwendende HTML-Element mit einem id-Attribut und verwenden sie DOM-Methoden (Kapitel auf dieser Seite). |
Namen von Methoden oder EigenschaftenMit eval können auch die Namen verschiedener Methoden variabel programmiert werden. Das Beispiel zeigt zuerst die einzelne Anwendung der Methoden play und stopMit eval lässt sich die angewendete Methode programmieren, z.B. m="play"; oder m="stop"; Als Sicherheits-Maßnahme wird der Befehl innerhalb eines try-Blocks ausgeführt: Wenn nicht existierende sound-Objekte oder unzulässige Methoden auftreten, wird der Befehl einfach ignoriert. |
Ohne eval: Methoden sind fix im Quellcode eingetragen
s = "sound1"; document.embeds[s].play(); document.embeds[s].stop(); Mit eval: Methoden sind variabel programmierbar
s = "sound1";
m = "play"; t = "document.embeds["+s+"]."+m+"();" try {eval(t);} catch(e) {} |
EigenschaftenDie große Zahl der CSS-Eigenschaften lässt sich mit eval variabel programmieren.Im Beispiel wird ein HTML-Element mit Hilfe seines id-Attributs identifiziert. Danach werden seine CSS-Eigenschaften height und width gelesen - zuerst fix, danach mit eval variabel programmiert. ♦ Details zu Objekten, Eigenschaften & Methoden. ♦ Details zu CSS, zur Adressierung von DOM-Elementen und zur Programmierung des style-Objekts mit Javascript. |
HTML:
<span id="test">Muster</span>
Ohne eval: Eigenschaften sind fix im Quellcode eingetragen
n = document.getElementById("test");
Mit eval: Eigenschaften sind variabel programmierbar
w = n.style.height; w = n.style.width;
n = document.getElementById("test");
p = "height"; eval("w=n.style."+p+";"); cssp = "width"; eval("w=n.style."+p+";"); |
Anwendung variabler Funktionen |
|
|
Mit eval ist es möglich, je nach Bedarf unterschiedliche
Funktionen auszuführen. Das Beispiel ist sowohl auf Standard Javascript-Funktionen als auch auf eigene Funktionen (hier add und sub) anwendbar. Das Konzept kann beliebig ausgeweitet werden: Durch Änderung des Befehls-Textes, können andere Variable oder eine andere Anzahl von Variablen eingesetzt werden, usw. |
Ohne eval ist die verwendete Funktion fix im Quelltext eingetragen:
r = add(a,b);
Mit eval sind Funktions-Namen (und die Namen der Variablen) programmierbar:
r = sub(a,b);
f = "add";
eval("r="+f+"(a,b);"); f = "sub"; eval("r="+f+"(a,b);"); |
Zuweisung JSON-formatierter Daten |
|
|
Funktion eval wird häufig im Zusammenhang mit
Ajax (Empfang von Daten und Objekten durch Javascript) verwendet. ● Ein Ajax-Server formatiert die angebotenen Daten und Objekte als Liste von Elementen, getrennt durch , Beistrich. Texte werden in "" eingeschlossen. (Beispiel rechts oben). ● Beim Empfang der Daten durch Javascript werden die Daten zunächst als Text an eine Variable (hier atxt) zugewiesen. ● Danach werden die Daten mit eval an ein Array (hier ar) übergeben. Durch die Interpretation wird aus jedem Element der Text-Liste ein Element des Javascript-Arrays. ● Das Array wird anschließend verarbeitet, je nach Aufgabe des Programms. |
Beispiel JSON-formatierter Daten:
12,34,"Rita","Stefan",789 Empfang der vom Ajax-Server erhaltenen Daten: var atxt = ajax_obj.responseText; Umwandlung in JSON-Syntax: atxt = "["+atxt+"]"; Interpretation mit eval: var ar = eval(atxt); Anwendung: alert(ar[2]);
ergibt Rita
|
|
Dieses Verfahren hat viele Vorteile: • Die Liste kann beliebig viele Elemente enthalten. • Die Elemente können gemischt Zahlen und/oder Text enthalten. |
●
Auf ähnliche Weise werden auch Objekte
inklusive ihrer Eigenschaften und Methoden JSON-codiert, übertragen und
mit eval decodiert. ♦ Details zu den Themen Ajax, Array, JSON, Objekt |
Ersatz von eval durch DOM-Methoden |
|
|
In manchen Fällen kann eval durch Anwendung von
DOM-Methoden ersetzt werden. Das Document Object Model (DOM) ist das grundlegende Konzept zur Verwaltung hierarchischer Objekte wie z.B. einer Webseite und aller darin enthaltener Elemente. Ein bestimmtes Element (hier: eine von vielen Zellen einer Tabelle) wird meist mit seinem id-Attribut adressiert, welches eindeutig sein muss. ▲ DOM-Methoden sind im Zweifel immer vorzuziehen: Sie arbeiten meist wesentlich schneller und sind zukunftssicher - Sie arbeiten mit allen Mitgliedern der XML-Familie, insbesondere auch mit XHTML. Das Beispiel rechts zeigt, wie man den aktuellen Wert aus den Zellen einer Tabelle mit DOM-Methoden lesen und schreiben (hier abgeschaltet) kann. Das id-Attribut wird als Text verwendet und lässt sich daher bequem in einer Schleife programmieren. ♦ Details zur Verwendung von DOM-Methoden mit Javascript. |
HTML-Tabelle:
<table>
<tr>
</table>
<td id="z1">123</td>
</tr><td id="z2">234</td> <tr>
<td id="z3">345</td>
</tr>
<td id="z4">456</td> <!-- weitere Zeilen... -->
Javascript mit DOM (einzeln)
n = document.getElementById("z1");
Das gleiche Beispiel in einer Schleife für 100 Zellen
w = n.firstChild.nodeValue; // n.firstChild.Value=987.toString();
for(i=1;i<100;i++) {
id = "z"+i.toString();
}
n = document.getElementById(id); w = n.firstChild.nodeValue; //n.firstChild.Value=987.toString();
|