Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 04-02-2006, 01:10   #1 (permalink)
web-addict
 
Registriert seit: Jun 2005
Ort: beautiful south
Beiträge: 36
Question verwirrung um .call() und .apply() funktionen

ich denke grundsätzlich habe ich schon verstanden was die beiden machen,
nämlich eine funktion auf einem anderen objekt, das diese funktion nicht
implementiert in dessen scope ausführt.

die .apply() funktion ist ja auch das kernstück des delegates/proxys
(beispiele dazu hier) .

nun habe ich mir mal die language-referrence/api dazu angeschaut und bin da
auch noch auf die .call() funktion gestossen.
mir scheint, dass die beide fast dasselbe machen, mit dem kleinen unterschied,
dass bei .call() die an die zielfunktion zu übergebenden parameter direkt als
parameter im .call() angehängt übergeben werden, wohingegen bei .apply() die
parameter in einem array und dessen inhalt als parameter übergeben wird, was
den vorteil hat, dass die anzahl der parameter nicht fest ist.

soweit so gut, nur ist mir aufgefallen, dass die beiden funktionen
unterschiedliche rückgabewerte in ihrer signatur angegeben haben:
- .apply() hat rückgabewert Void (also 'nix')
- .call() hat rückgabewert Object

ich kann mir nicht so recht vorstellen wie das gemeint sein soll.

weiterhin kommt mir das beispiel zur .call() funktion ziemlich mysteriös vor:

Code:
// so stehts in der referenz
function myObject() {
}

function myMethod(obj) {
    trace("this == obj? " + (this == obj));
}

var obj:Object = new myObject();

myMethod.call(obj, obj);
ich mein ok, es funktioniert ja, aber warum zum geier wird myObject zunächst
als function deklariert und dann aber neu instantiiert und der als Object
typisierten Variable obj zugewiesen??? das hat doch nichts mit der
eigentlichen funktionalität der .call() funktion zu tun, oder?

wär das beispiel so nicht irgendwie weniger verwirrend und korrekter?
Code:
function myMethod(param) {
    trace("this == obj? " + (this == param));
}

var obj:Object = new Object();

myMethod.call(obj, obj);
und dann noch was zu dem ominösen rückgabewert der .call() bzw. .apply() fkt:
Code:
var myMethod:Function;

function myMethodVariation1(param) {
    trace("this == obj? " + (this == param));
}

function myMethodVariation2(param) {
    trace("this == obj? " + (this == param));
	return "blubb";
}

var obj:Object = new Object();

var strangeReturnObject:Object;

this.myMethod = this.myMethodVariation1;
this.strangeReturnObject = myMethod.call(obj, obj);
trace(strangeReturnObject); // undefined

trace("-----------------");

this.myMethod = this.myMethodVariation2;
this.strangeReturnObject = myMethod.call(obj, obj);
trace(strangeReturnObject); // blubb

trace("-----------------");

var objArr:Array = new Array(this.obj);

this.myMethod = this.myMethodVariation1;
this.strangeReturnObject = myMethod.apply(obj, objArr);
trace(strangeReturnObject); // undefined

trace("-----------------");

this.myMethod = this.myMethodVariation2;
this.strangeReturnObject = myMethod.apply(obj, objArr);
trace(strangeReturnObject); // blubb
also enweder geben beide funktionen ( .call() und .apply() ) beliebige objekte
der aufgerufenen funktion zurück oder ich hab da was falsch verstanden ...

was meint ihr?
antiplex ist offline   Mit Zitat antworten
Alt 04-02-2006, 05:43   #2 (permalink)
Techniker
 
Benutzerbild von hgseib
 
Registriert seit: Sep 2003
Ort: 64807
Beiträge: 18.086
"..und dann noch was zu dem ominösen rückgabewert.."
der aber genau so im handbuch steht:
public call(thisObject:Object, [parameter1:Object]) : Object
public apply(thisObject:Object, [argArray:Array]) : Void
so gesehen hasst du gerade eben das rad nochmal neu erfunden ;-)


warum es zwei funktionen gibt verstehe ich allerdings auch nicht so ganz. natürlich kann ein parameter von call auch ein array sein.

ein unterschied ist halt, das ein array ein zeiger auf einen block von variablen ist und somit eine veränderung in der function die originalwerte ändert.
demgegenüber werden bei einfachen variablen (zahlen) deren inhalt übergeben. womit eine veränderung in der function die originalwerte nicht ändert.

ich persönlich kann also ganz gut auf apply verzichten. aber bitte, da gibt es diskusionswürdigere themen.
Code:
var _array = [1, 2, 3];
var obj2:Object = new Object();
var obj1:Object = new Object();
obj1.fTest1 = function(_array) {
	_array[0]++;
	trace(_array);
};
obj1.fTest2 = function(x, y, z) {
	x++;
	return [x, y, z];
};
//
obj1.fTest1(_array);
obj1.fTest1.call(obj2, _array);
trace(_array);
trace(" ");
var _array2 = obj1.fTest2.call(obj2, _array[0], _array[1], _array[2]);
trace(_array);
trace(_array2);
__________________
die ultimative antwort auf alle programmierfragen: der debugger
mfg h.g.seib www.SeibsProgrammLaden.de

Geändert von hgseib (04-02-2006 um 05:44 Uhr)
hgseib ist offline   Mit Zitat antworten
Alt 04-02-2006, 10:10   #3 (permalink)
Nagelneuer User
 
Benutzerbild von hazy fantazy
 
Registriert seit: Dec 2005
Beiträge: 923
@hgseib: apply ist dann sinnvoll, wenn du nicht weisst, wieviele Parameter deine Funktion bekommt.

Code:
    //ohne apply function machAlles(){     if( arguments.length == 0) machWas(arguments[0]);     if( arguments.length == 1) machWas(arguments[0], arguments[1]);     if( arguments.length == 1) machWas(arguments[0], arguments[1], arguments[2]);      //...    //mit applyfunction machAlles(){     machWas.apply( this, arguments);} function machWas(){      trace("machWas " + arguments);}//aufrufmachAlles(1,2);machAlles(1,2,3,4,5); //klappt nicht mit der ersten Version

@antiplex
Die Doku ist nicht immer 100prozentig. Natürlich liefern beide das Ergebnis der Funktion, die du aufrufst. Was anderes macht auch keinen Sinn.

mfg. h
__________________
The fact that you've got "Replica" written on the side of your gun and the fact that I've got "Desert Eagle written on the side of mine ... :D
hazy fantazy ist offline   Mit Zitat antworten
Alt 04-02-2006, 13:43   #4 (permalink)
web-addict
 
Registriert seit: Jun 2005
Ort: beautiful south
Beiträge: 36
@hgseib:
... " der aber genau so im handbuch steht:
public call(thisObject:Object, [parameter1:Object]) : Object
public apply(thisObject:Object, [argArray:Array]) : Void
so gesehen hasst du gerade eben das rad nochmal neu erfunden ;-) " ...

na genau das war ja das was mich verwirrt hat, denn apply hat offensichtlich
nicht rückgabewert 'Void' sondern ebenfalls 'Object' . war mir jetzt nur nicht
sicher ob ich da irgendwas ver-raffe oder ob die doku da 'buggy' ist.

aber danke für die erläuterung bzgl wert und referenzübergabe, schön das flash
das sauber handhabt und gut das mal wieder vergegenwärtigt zu haben.

"... da gibt es diskusionswürdigere themen."
aber klar, das ist jetzt nicht das riesen ding, mir gings ja auch noch um das
beispiel in der doku was mich auch mehr verwirrt als zum verständnis beigetragen hat.
macht das evtl sinn in dieser kleinigkeit mal an macromedia zu schreiben und
einen verbesserungsvorschlag einzureichen?


@hazy fantazy:
"@hgseib: apply ist dann sinnvoll, wenn du nicht weisst, wieviele Parameter
deine Funktion bekommt. "
genau das meinte ich mit "... was den vorteil hat, dass die anzahl der parameter nicht fest ist." .

richtig, das mit 'Void' als rückgabe macht wirklich keinen sinn, ich hab halt erst
mal an mir und dann an der doku gezweifelt


danke euch vielmals für die bestätigung bzw erläuterungen!
antiplex ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 21:38 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2014 Marc Thiele