AdiK: Sicherstellen, dass Funktion als Konstruktor aufgerufen wird

Hallo zusammen,
wäre wiedermal froh, um eure Hilfe:

Wie kann sichergestellt werden, dass eine Funktion als Konstruktor aufgerufen wird (weil sie sonst nämlich keinen Sinn macht)?

Und wie kann sichergestellt werden, dass der Konstruktor die richtigen Typen in den Argumenten bekommen? Ich habe das bis anhin mit 'throw' gemacht:

function X(s) {  
  if (typeof s != 'number') throw 'Give a number!';  
  this.inc = function() {s++};  
  this.show = function(){alert(s)}  
}

Gruss,
Adi

  1. Wie kann sichergestellt werden, dass eine Funktion als Konstruktor aufgerufen wird (weil sie sonst nämlich keinen Sinn macht)?

    »Als Konstruktor aufrufen« ist nichts anderes als dass die Funktion im Kontext eines neuen, leeren Objektes ausgeführt wird. Daher ist es nicht so einfach möglich, das abzufragen. Du kannst höchstens abfragen, ob sie nicht über X() ohne »new« aufgerufen wurde - dann würde this nämlich auf window zeigen (this muss !== window sein). Allerdings gibts viele weitere Möglichkeiten, die Funktion »falsch« aufzurufen, ohne dass this auf window zeigt. Aber die Abfrage, ob window !== this bzw. ungleich dem Objekt ist, an dem du die Konstruktorfunktion vielleicht gruppierst, dürfte schon die häufigste Fehlbenutzung abdecken.

    Und wie kann sichergestellt werden, dass der Konstruktor die richtigen Typen in den Argumenten bekommen? Ich habe das bis anhin mit 'throw' gemacht

    Das ist schon ganz richtig.

    function X(s) {
      if (typeof s != 'number') throw 'Give a number!';

    Hier solltest du aber besser throw new Error('Give a number!'); schreiben.

    Mathias

    1. Hallo Mathias

      Vielen Dank für deine Erklärung!

      Gruss und schönen Sonntag noch,
      Adi

  2. gruss Adi,

    molily ergaenzend lenke ich den blick auf folgenden vergleich

    (this.constructor !== arguments.callee) und empfehle zu diesem

    thema als zusaetzliche lektuere:

    so long - peterS. - pseliger@gmx.net

    --
    »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
    Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
    ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
    1. Hallo Peter

      Herzlichen Dank für deinen tollen Tipp!

      Ich habe auch die Threads mit grossem Interesse durchgelesen, denn JavaScript ist definitiv meine Lieblingssprache! :-)

      Gruss, Adi

  3. Hallo,

    Wie kann sichergestellt werden, dass eine Funktion als Konstruktor aufgerufen wird (weil sie sonst nämlich keinen Sinn macht)?

    schreib eine ordentliche Doku, ich persönlich würde aus performancegründen auf solche tests wie constructor == callee verzichten.
    wers falsch benutzt ist selber schuld (und lernt durch die "ich kann ja eigentlich machen was ich will, es funktioniert, auch nicht wie es richtig geht", und fällt bei bibliotheken, die keinen phpnoobmode bieten, gehörig aufs gesicht).

    Und wie kann sichergestellt werden, dass der Konstruktor die richtigen Typen in den Argumenten bekommen? Ich habe das bis anhin mit 'throw' gemacht:

    ich würde dort eher mit https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/TypeError um mich werfen anstatt mit error.

    Tschö

    1. ich persönlich würde aus performancegründen auf solche tests wie constructor == callee verzichten.

      Mit dem Argument könnte man auch auf die Validierung der Parameter und das Werfen von Exceptions im Fehlerfalle verzichten.

      wers falsch benutzt ist selber schuld (und lernt durch die "ich kann ja eigentlich machen was ich will, es funktioniert, auch nicht wie es richtig geht"

      Wer redet denn davon, dass es trotzdem funktioniert? Wenn eine Funktion nicht als Konstruktor aufgerufen wurde, es aber erfordert, dann sollte man einen entsprechenden Fehler werfen. Das hatten wir auch im bereits verlinkten Thread </archiv/2008/11/t179319/#m1183350> ff.

      Mathias