wiberg: Probleme mit Funktionsaufruf

Hallo,

die Funktion (eig. eine Methode) "move" ruft sich selbst nach einer gewissen Zeit auf - leider scheint sie nicht mehr zu wissen, dass sie eine Methode von einem Objekt ist. Sie kann dann nicht mehr auf die Eigenschaften des Objekts zugreifen. Warum?
Code:

das Objekt sieht so aus:

function Sn(color) {
    this.posx = Math.floor(size / 2);
    this.color = color;
    this.move = move;
}

function move() {
  document.getElementById(this.posx).style.color = "#" + this.color;
  window.setTimeout("this.move();",this.speed);
}

  1. Hi wiberg,

    die Funktion (eig. eine Methode) "move" ruft sich selbst nach einer gewissen Zeit auf - leider scheint sie nicht mehr zu wissen, dass sie eine Methode von einem Objekt ist. Sie kann dann nicht mehr auf die Eigenschaften des Objekts zugreifen. Warum?

    Weil beim zweiten mal, die Function aus einer Function heraus aufgerufen wird und nicht aus einem Objekt. Aus dem Grund führt das this dann zu nichts mehr.

    MfG, Dennis.

    --
    Mein SelfCode: ie:{ fl:{ br:^ va:) ls:< fo:) rl:( n4:& ss:) de:> js:( ch:{ sh:( mo:} zu:|
    Zufällige Hinweise:
    ------------------------
    Wer die </faq/> gelesen hat, ist klueger!
    ... und wei wie man Links macht ;-)
  2. Hi!

    function move() {
      document.getElementById(this.posx).style.color = "#" + this.color;
      window.setTimeout("this.move();",this.speed);}

    ^^
    Der Fehler liegt hier:------------->
    Dort gehört nämlich kein Semikolon hin. Richtig müsste es so heißen:

    windowsetTimeout("this.move()", this.speed);

    ---------------------------------------------------------

    Grüße,

    Fabian St.

  3. gruss wiberg,

    function move() {
      document.getElementById(this.posx).style.color = "#" + this.color;
      window.setTimeout("this.move();",this.speed);

    -----------------------^^^^^^^^^^^^^^

    spaetestens an dieser stelle ist der interpreter ueberfordert, da "this.move();"
       von der funktion "setTimeout" nicht mehr im richtigen kontext evaluiert werden
       kann oder einfacher ausgedrueckt: "setTimeout" kann "this.move()" nirgendwohin
       zuordnen, da "this" als zeichenkette innerhalb von "setTimeout" nicht mehr den
       bezug zur methode "move" aufrechterhalten kann;

    }

    es muss also ein weg gefunden werden, der die referenz auf das objekt trotz der
       gerade beschriebenen einschraenkungen durch "setTimeout" permanent ermoeglicht;

    zur veranschaulichung schlage ich ersteinmal die "unsaubere" loesung vor, mit
       namen von globalen variablen zu arbeiten; jedes objekt, welches spaeter die
       "move"-methode aufrufen soll, benoetigt eine zusaetzliche eigenschaft, in der
       sein globaler variablenname hinterlegt wird;

    dieser name wird dann beim erstmaligen aufruf der methode mitgegeben und von
       ebenjener dann permanent durchgeschliffen;

    dein abgewandeltes bsp.:

    function Sn(color) {
       //this.posx = Math.floor(size/2);
         this.color = color;
         this.move = move;
       }
       function move(globalName,objectSpeed) {
       //document.getElementById(this.posx).style.color = "#" + this.color;
         alert("color = " + window[globalName].color + "\nspeed = " + objectSpeed);
         window.setTimeout(("window["" + globalName + ""].move("" + globalName + ""," + objectSpeed + ")"),objectSpeed);
       }
       var x = new Sn("ffcc00");

    x.globalName = "x";
       x.speed = 3000;

    x.move(x.globalName,x.speed);

    ausserdem ist es ratsam, eigenschaften und methoden, die allen instanzen eines
       konstruktors gemein sind, als prototypen der konstruktor-funktion zu realisieren -

    fuer den oben beschriebenen fall saehe das so aus:

    var Sn = function(color) {
       //this.posx = Math.floor(size/2);
         this.color = color;
       };
       Sn.prototype.move = function(globalName,objectSpeed) {
       //document.getElementById(this.posx).style.color = "#" + this.color;
         alert("color = " + window[globalName].color + "\nspeed = " + objectSpeed);
         window.setTimeout(("window["" + globalName + ""].move("" + globalName + ""," + objectSpeed + ")"),objectSpeed);
       };
       Sn.prototype.speed = 3000; // time in msec;

    var x = new Sn("ffcc00");

    x.globalName = "x";

    x.move(x.globalName,x.speed);

    falls jetzt noch interesse an einem dieses thema ausfuehrlich diskutierenden
       und beschreibenden thread besteht, empfehle ich als einstieg folgendes posting -

    http://forum.de.selfhtml.org/archiv/2004/3/77173/#m445704 - sowie die

    dort verlinkte javascript-loesung:

    http://www.pseliger.de/jsExtendedApi/jsApi.Object.selfReferences.dev.js

    viel erfolg - peterS. - pseliger@gmx.net

    --
    sh:| fo:) ch:? rl:| br:& n3:} n4:# ie:| mo:{ va:| de:[ zu:] fl:) ss:) ls:& js:)
  4. Vielen Dank für diese ausführliche Hilfe, aber das ist nicht ganz das, was ich suche. Ich habe mal eine Methode ausgegraben, die sich selbst ohne Probleme als Methode einer existierenden Instanz aufrufen konnte:

    function Effect() {
         this.moveL = moveL;
       }

    function moveL(element_id,start,end,i) {

    if(typeof(i) == 'undefined')
           var i = 50;

    var new_pos = end + ((start - end) / (51 - i));

    //alert(end + " + ((" + start + " - " + end + ") / (51 - " + i + ")) = " + new_pos);

    document.getElementById(element_id).style.left = new_pos + "px";

    if(i > 0) {
           --i;
           window.setTimeout("this.moveL('" + element_id + "'," + start + "," + end + "," + i + ");",10);
         }// else alert("Endwert: " + new_pos);
       }

    ich gebe zu, dass ist ein bisschen holprig programmiert, aber es erfüllte seinen Zweck. Man konnte damit ein Objekt ziemlich fesch durch die Gegend flitzen lassen... und wie man sieht, ruft sich moveL() selbst mit einem Timeout auf (übrigens MIT Semikolon). Seltsam, ich finde, dass meine jetzige Funktion dieser sehr ähnlich sieht, dennoch funktioniert sie nicht.