JavaScript: Funktionen und Argumente

Aus der (jetzt startenden) Serie: Wissenswertes zu JavaScript, das vermutlich nicht jeder drauf hat

Explizit deklarierte Parameter

Ich vermute, jeder Leser kennt Funktionen dieser Art:

make_doc( "eine Seite", "preset" );
 
function make_doc( the_name, the_preset ) {
  the_preset = app.documentPresets.item( the_preset ).isValid ?
    app.documentPresets.item( the_preset ) : 
    app.documentPresets.item( 0 );
  return app.documents.add( true, the_preset, { name: the_name } );
}

Der gebräuchlichste Fall ist, dass man bei der Deklaration der Funktion explizit angibt, welche Parameter dieser Funktion übergeben werden sollen.

Zum guten Stil gehört, dass man die Werte der Parameter prüft, bevor man sie anwendet, wie hier mit dem preset, aber sonst gilt: What you see is what you get.

Optionale Parameter

Aktuelle Versionen von JavaScript (also nicht die Version, die der InDesign-Interpreter kann 😉) können in der Funktionsdeklaration gleich den Vorgabewert deklarieren:

function format_text( familie="Avenir", schnitt="55-Roman", grad=12, farbe="Black") {}
format_text( undefined, undefined, 24 );

Sprich: Beim Aufruf kann man die Parameter, die man auf default lassen will, einfach weg lassen (auf undefined lassen) und die Funktion nimmt dann die Vorgabe.

Das geht natürlich auch in InDesigns ExtendScript, ist aber ein wenig umständlicher:

function format_text ( familie, schnitt, grad, farbe ) {
  if ( !familie ) familie = "Avenir";
  if ( schnitt === undefined ) schnitt = "55-Roman";
  grad = grad ? grad : 12;
  farbe = farbe || "Black";
}

Die vier Check-Varianten sind nicht exakt gleichwertig, aber in diesem Fall gehen alle vier.

Der implizite Parameter arguments

Im Objektmodell Viewer heißt es zu den Eigenschaften von function:

Was bedeutet das?

Mit der Minimalanwendung wird das vielleicht deutlicher:

meine_funktion( 1, 2, "drei", (8/2) );
function meine_funktion() {
  $.writeln( arguments.toSource() );
}

Das schreibt in die Console (ohne das Pretty Print 😉 ):

({
	length: 4,
	callee: (function meine_funktion() {
		$.writeln(arguments.toSource());
	}),
	0: 1,
	1: 2,
	2: "drei",
	3: 4
})

Mit arguments kommen wir also an eine Art Array ran, das all die übergebenen Parameter enthält.

Und wofür ist das gut?

In vielen JavaScript-Umgebungen gibt es Funktionen, mit denen man einen String so zusammen setzen kann:

make_string( 
  "Als %1 %2 sah, sagte er zu %3: 'Schau, %3, das ist %2'",
  "Peter",
  "Paul",
  "Maria"
);
// => "Als Peter Paul sah, sagte er zu Maria: 'Schau, Maria, das ist Paul'"

Jede Zahl nach Prozentzeichen wird also gegen einen der folgenden Parameter ausgetauscht.

Das Problem bei der Funktion make_string ist, dass ich vorher nicht weiß, wieviele Ersetzungen stattfinden sollen.

Mit dem arguments Parameter kann ich diese Funktion aber bauen. Zum Beispiel so:

$.writeln( build_line() );
$.writeln( build_line( "Hallo Du" ) );
$.writeln( build_line( "Hallo %1", "Gerald" ) );
$.writeln( build_line( "Hallo %1, ich bin %2" , "Gerald", "Singel" ) );
$.writeln( build_line( "Hallo %1, ich bin %2" , [ "Gerald", "Singel" ] ) );
 
 
 
function build_line() {
  if (arguments.length == 0) {
    return "\n";
  } else if ( arguments.length == 1 ) {
    return arguments[0] + "\n";
  } else {
    var a = arguments[0];
    var b = (arguments[1].constructor.name == "Array") ? [""].concat( arguments[1] ) : arguments;
    for (var n = b.length-1; n > 0; n--) {
      var re = new RegExp( "%" + n, "g" );
      a = a.replace( re, b[n].toString() );
    }
    return a + "\n";
  }
}

Hier habe ich’s noch etwas aufgebohrt, so dass die Einfüll-Parameter entweder einzeln oder als Array übergeben werden können.

Wenn Sie also mal wieder Strings flexibel zusammensetzen müssen, kennen Sie jetzt einen hübschen neuen Ansatz.