molily: pass by reference - verständnisproblem

Beitrag lesen

»»» Kannst Du mir vielleicht noch bei der Funktion once() weiterhelfen?

my_inputs = "fourthInput";  
do_it(my_inputs, once(storer(my_object, 'blah')));  
alert("first call do_it: " + my_object.blah); //fourthInput  
my_inputs = "fifthInput";  
do_it(my_inputs, once(storer(my_object, 'blah')));  
alert("second call do_it: " + my_object.blah);//fifthInput

Du rufst once() hier zweimal auf. once gibt jeweils eine Funktion zurück, die man nur einmal nutzen kann. Sie wrappt dazu die übergebene Funktion.

Der Witz hier ist eben, dass du die Funktion nur einmal nutzt. Beim zweiten mal verwendest du sie nicht wieder, sondern legst eine neue Funktion an, indem du once() nochmal aufrufst.

Was du hier machst, ist äquivalent zu folgendem:

var once1 = once(storer(my_object, 'blah'));  
once1("fourthInput");  
alert(my_object.blah); //fourthInput  
  
var once2 = once(storer(my_object, 'blah'));  
once2("fifthInput");  
alert(my_object.blah); //fifthInput

once1 ist eine andere Wrapperfunktion als once2. Crockford aber redet davon, dass once1 nur einmal verwendet werden kann. Versuch sie mal wiederzuverwenden:

var once_storer = once(storer(my_object, 'blah'));  
  
once_storer("fourthInput");  
alert(my_object.blah); //fourthInput  
  
once_storer("fifthInput"); // Exception

Das geht natürlich nicht, weil die Wrapper-Funktion das verhindert.

Deine Beispiele sind auch etwas gestellt. Crockford redet von asynchronen Callbacks z.B. bei Ajax, beim Abarbeiten von Listen oder einfach dem Ausführen verschiedener Aufgaben hintereinander. do_it() macht also nur Sinn, wenn es einen Payload hat, der ausgeführt wird, bevor das Ergebnis an die Callback-Funktion weitergegeben wird (in deinen Beispiel ist es nur ein unnötiger Wrapper). Dazu beschreibt er die Möglichkeit, Callbacks funktional zu erzeugen, sodass sie gemäß dem »object capability security system« Zugriff auf die nötigen Daten »by introduction« haben und auf keine sonstigen Daten. Es geht hier um die Trennung von Aufgaben und damit die Trennung von Zugriffsrechten, deshalb betont er ständig »none of this is do_it's business«. In dem Zusammenhang soll die Ausführung von Callbacks durch das wrappen mit once() limitiert werden. Das ist eben weder die Aufgabe von do_it noch des Callbacks an sich. Wichtig ist hier, dass do_it keinen direkten Zugriff auf den Callback hat (technisch gesehen in deinen Beispielen schon, aber das soll eben vermieden werden). Es bekommt nur die Wrapper-Funktion übergeben. Und diese kann eben nur einmal ausgeführt werden.

Mathias