nam: Wo liegt mein Denkfehler?

Hallo

Es ist kurz nach Mittag und mein Blut ist im Verdauungstrakt, statt im Hirn.
Habe folgenden Code (vereinfacht):

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"  
        "http://www.w3.org/TR/html4/strict.dtd">  
  
<html>  
<head>  
<title>hyph.js - test</title>  
<meta http-equiv="content-type" content="text/html; charset=UTF-8">  
<meta http-equiv="Content-Script-Type" content="text/javascript">  
<script type="text/javascript">  
var foo='test';  
function overwrite(fn) {  
 fn='t';  
}  
</script>  
</head>  
<body>  
<p>  
<a href="#" onclick="overwrite(foo);">Click1</a><br>  
<a href="#" onclick="alert(foo);">Click2</a>  
</p>  
</body>  
</html>  

Bei Klicks auf Click1 und dann auf Click2 erwarte ich - offenbar irrtümlicherweise - ein alert mit 'bar'.
Ist aber 'foo'. Das heisst, die Variable foo wird nicht überschrieben.

Wo ist der Denkfehler/die Wissenslücke?

Danke und Gruss,
Mathias

  1. Sry:

      
    <script type="text/javascript">  
    var foo='foo';  
    function overwrite(fn) {  
     fn='bar';  
    }  
    </script>  
    
    

    Dann stimmts mit dem Text überein.

  2. <script type="text/javascript">
    var foo='test';
    function overwrite(fn) {
    fn='t';
    }

    einfache Datentypen, werden in JS nicht als Referenzen übergeben. D.h. du müßtest hier eigentlich eine Fehlermeldung erhalten (Fehlerkonsole ist tatsächlich leer?), da fn der string 'test' ist und 'test' = 't' geht nicht.

    Struppi.

    1. einfache Datentypen, werden in JS nicht als Referenzen übergeben. D.h. du müßtest hier eigentlich eine Fehlermeldung erhalten (Fehlerkonsole ist tatsächlich leer?), da fn der string 'test' ist und 'test' = 't' geht nicht.

      Nein, keine Fehlermeldungen (Firefox, Safari).
      Was sind einfache Datentypen? Bzw. was sind den 'komplexe' Datentypen (in JS natürlich)?

      Bei Funktionen funktionierts (*grins*) auch nicht:

        
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"  
              "http://www.w3.org/TR/html4/strict.dtd">  
      <html>  
      <head>  
      <title>hyph.js - test</title>  
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
      <meta http-equiv="Content-Script-Type" content="text/javascript">  
      <script type="text/javascript">  
      var foo=function() {  
       alert('foo')  
      };  
      function overwrite(fn) {  
       fn=function() {  
        alert('bar');  
       };  
      }  
      </script>  
      </head>  
      <body>  
      <p>  
      <a href="#" onclick="overwrite(foo);">Click1</a><br>  
      <a href="#" onclick="foo();">Click2</a>  
      </p>  
      </body>  
      </html>  
      
      

      Alertet auch 'foo'.

    2. @@Struppi:

      var foo='test';
      function overwrite(fn) {
      fn='t';
      }

      einfache Datentypen, werden in JS nicht als Referenzen übergeben. D.h. du müßtest hier eigentlich eine Fehlermeldung erhalten (Fehlerkonsole ist tatsächlich leer?), da fn der string 'test' ist und 'test' = 't' geht nicht.

      ?? 'fn' ist innerhalb der Funktion eine lokale Variable und fn = 't'; geht doch.

      Live long and prosper,
      Gunnar

      --
      „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
    3. Hallo Struppi,

      <script type="text/javascript">
      var foo='test';
      function overwrite(fn) {
      fn='t';
      }

      einfache Datentypen, werden in JS nicht als Referenzen übergeben.

      sondern als Wert, Aufrufmethode "Call by value".

      D.h. du müßtest hier eigentlich eine Fehlermeldung erhalten (Fehlerkonsole ist tatsächlich leer?), da fn der string 'test' ist und 'test' = 't' geht nicht.

      Nein, wieso sollte es zu einer Fehlermeldung kommen?

      fn ist eine Variable, eine lokale Variable innerhalb der Funktion. Dieser wird bei beiden Funktionsaufrufen der Wert 'test' zugewiesen. Es ist kein Problem, dieser Variablen den Wert 't' zuzuweisen, der anschließend entsorgt wird, da die Funktion beendet ist und die Variable fn somit ihr Leben aushaucht bis sie beim nächsten Funktionsaufruf wieder aufersteht und mit dem übergebenen Wert neu gefüllt wird. Dieser wird wieder zu 't' geändert und unmittelbar danach ist das kurze Leben von fn wieder vorbei.

      Ich sehe keinen Grund, warum es zu einer Fehlermeldung kommen sollte. Syntaktisch ist doch alles korrekt.

      Freundliche Grüße

      Vinzenz

  3. Hallo Mathias,

    <script type="text/javascript">
    var foo='test';

    function overwrite(fn) { // Der Aufrufparameter fn ist eine lokale Variable
    fn='bar';               // Diese lokale Variable hat nun den Wert 'bar'
    }                        // Nach Beendigung der Funktion ist das Leben dieser

    // lokalen Variablen beendet

    // Du möchtest hingegen den Wert der "globaleren" Variablen foo ändern.

    [...]

    <a href="#" onclick="overwrite(foo);">Click1</a><br>
    <a href="#" onclick="alert(foo);">Click2</a>

    
    > Bei Klicks auf Click1 und dann auf Click2 erwarte ich - offenbar irrtümlicherweise - ein alert mit 'bar'.  
    > Ist aber 'foo'. Das heisst, die Variable foo wird nicht überschrieben.  
    >   
    > Wo ist der Denkfehler/die Wissenslücke?  
      
    SELFHTML, Abschnitt [Variablen definieren](http://de.selfhtml.org/javascript/sprache/variablen.htm).  
      
    Grundsätzlich ist es eine gute Idee, nur so wenige globale Variablen zu verwenden, wie möglich. Packe doch Dein foo als Eigenschaft in ein Objekt und ändere den Wert dieser Objekteigenschaft.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. // Der Aufrufparameter fn ist eine lokale Variable
      // Diese lokale Variable hat nun den Wert 'bar'
      // Nach Beendigung der Funktion ist das Leben dieser
      // lokalen Variablen beendet

      Ja, aber in dieser lokalen Variable fn ist eine Referenz auf foo gespeichert, oder?

      Merkt denn JS nicht, dass ich nicht die Referenz überschreiben will, sondern den Inhalt der referenzierten Variable?

      1. Yerf!

        Ja, aber in dieser lokalen Variable fn ist eine Referenz auf foo gespeichert, oder?

        Nein

        Merkt denn JS nicht, dass ich nicht die Referenz überschreiben will, sondern den Inhalt der referenzierten Variable?

        Merke: ein Computer macht nicht das was du willst sondern das was du programmierst.

        Gruß,

        Harlequin

        --
        <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->
        1. Ja, aber in dieser lokalen Variable fn ist eine Referenz auf foo gespeichert, oder?
          Nein

          Das passiert, wenn man die Antworten in der falschen Reihenfolge liest.

          Merkt denn JS nicht, dass ich nicht die Referenz überschreiben will, sondern den Inhalt der referenzierten Variable?

          Merke: ein Computer macht nicht das was du willst sondern das was du programmierst.

          Also, Folgefrage:
          Wie mach ich das denn?
          Da ist Javascript ja ziemlich verschwenderisch mit Speicherplatz, wenn es alle Daten kopiert statt referenziert. Gibts in JS denn gar keine Referenzen?

          1. Wie mach ich das denn?

            Das was du willst geht so gar nicht. (Wobei mir nicht ganz klar ist was du willst).

            Da ist Javascript ja ziemlich verschwenderisch mit Speicherplatz, wenn es alle Daten kopiert statt referenziert. Gibts in JS denn gar keine Referenzen?

            Da habe ich faklsche Hoffnungen geweckt, doch JS übergibt alles ausser einfache Datentypen, also Zahlen und Strings, als Referenz, aber nicht als Zeiger, d.h. du kannst die Referenz nicht ändern, aber z.b. erweitern.

            Struppi.

          2. @@nam:

            Wie mach ich das denn?

            Nach Möglichkeit keine globalen Variablen verwenden.

            Ansonsten:

            function overwrite(fn)  
            {  
              window[fn] = 't';  
            }
            

            Achtung! Aufruf mit 'overwrite("foo");'.

            Live long and prosper,
            Gunnar

            --
            „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
            1. @Gunnar:
              Danke jetzt klappts:

                
              <script type="text/javascript">  
              var foo=function() {  
                alert('foo');  
              };  
              function overwrite(fn) {  
               window[fn]=function() {  
                alert('bar');  
               };  
              }  
              </script>  
              </head>  
              <body>  
              <p>  
              <a href="#" onclick="overwrite('foo');">Click1</a><br>  
              <a href="#" onclick="foo();">Click2</a>  
              </p>  
              
              

              @Struppi:

              Das was du willst geht so gar nicht. (Wobei mir nicht ganz klar ist was du willst).

              Was ich will ist einen Wert einer Variable des äusseren Scopes in einer Funktion ändern, wobei der Name der Variable dieser Funktion übergeben wird, weil der je nach Umstand ein anderer ist (sonst könnte ich den Wert ja direkt ansprechen).
              Jetzt gehts, dank Gunnar.

              Danke an euch alle und Gruss,
              Mathias

              1. @Struppi:

                Das was du willst geht so gar nicht. (Wobei mir nicht ganz klar ist was du willst).

                Was ich will ist einen Wert einer Variable des äusseren Scopes in einer Funktion ändern, wobei der Name der Variable dieser Funktion übergeben wird, weil der je nach Umstand ein anderer ist (sonst könnte ich den Wert ja direkt ansprechen).

                Den äußeren Scope kannst du nicht ansprechen, nur den globalen window oder einen definierten in der Funktion.

                Struppi.