2010-04-03 4 views
4

Je suis en train d'intégrer javascript et j'ai quelques difficultés à créer un prototype via un prototype.
J'ai ceci:Aide sur l'objet prototype

<script type="text/javascript"> 

     function myclass(a, b, c) { 
      if (arguments.length) { this.Init(a, b, c); } 
     } 
     myclass.prototype.Init = function(a, b, c) { 
      this.param1 = a; 
      this.param2 = b; 
      this.param3 = c; 
     }; 
     myclass.prototype.Print = function() { 

      alert(this.param1 + '-' + this.param2 + '-' + this.param3); 
     }; 

     var myObject = myclass(3, 5, 6); 
     myObject.Print(); 


    </script> 

mais je reçois une erreur en ligne avec this.Init (a, b, c);
Erreur: Cet objet ne gère pas cette propriété ou méthode

Répondre

3

Vous avez oublié le mot-clé new lorsque vous déclarez myObject:

var myObject = new myclass(3, 5, 6); 
+3

La raison pour laquelle cela n'a pas fonctionné est que lorsque vous utilisez le mot-clé 'new', 'this' dans le constructeur pointe vers l'instance que vous venez de créer. Cependant, en oubliant le 'new', le mot clé' this' est assigné à l'objet window, donc vous appelez window.Init; ce qui est à juste titre à l'origine de l'objet ne supporte pas cette propriété ou erreur de méthode :).En raison de ce danger, il est habituel que les fonctions destinées à être utilisées comme constructeurs soient nommées en commençant par une lettre majuscule (My_Class) afin qu'il soit plus facile de repérer un 'new' manquant – Matt

0

Juste par curiosité est-il une raison particulière que vous avez un « init » séparée méthode?

La fonction qui définit votre "classe" s'appelle le "constructeur" et vous pouvez simplement y effectuer la configuration. Si vous vouliez "ré-initialiser" l'objet, alors cela peut être utile mais cela ne semble pas servir un point ici.

Par exemple:

// You might as well start wrapping your code now: 

var myExample = (function myExample() { 

    // A common convention is to start the name of constructors with a 
    //  capital letter, one reason is it help makes it more obvious 
    //  when you forget the new keyword...Whether you use it or not 
    //  is up to you. Also note, calling it "MyClass" is a little 
    //  misleading because it's not a "class" really. You might 
    //  confuse yourself if you think of it as a class too much. 
    //  If you're wondering why I put the name twice, it's because 
    //  otherwise it would be an anonymous function which can be 
    //  annoying when debugging. You can just use var MyClass = function() {} 
    //  if you want 

    var MyClass = function MyClass(a, b, c) { 

     // This will set each parameter to whatever was provided 
     //  or if nothing is provided: null. If you leave out 
     //  the || "" part then any 
     //  time a value is not provided the parameter will 
     //  return "undefined". This may be what you want in some cases. 

     this.param1 = a || ""; 
     this.param2 = b || ""; 
     this.param3 = c || ""; 
    }; 

    // likewise it's convention to start most variables/functions lowercase 
    //  I think it's easier to type/looks better, but do as you please. 

    MyClass.prototype.print = function print() { 
     alert(this.param1 + '-' + this.param2 + '-' + this.param3); 
    }; 

    var myObject = new MyClass(); 
    myObject.print(); 
}()); 

Le « emballage » est

(function() { 
//your code here 
}()); 

Il est surtout inutile, mais il est quelque chose que vous aurez à commencer à faire par la suite si pourrait tout aussi bien commencer maintenant. C'est juste une façon de "boucler" il y en a d'autres aussi. Fondamentalement, la façon dont votre script a été écrit, si l'utilisateur a couru un autre script qui avait une fonction appelée MyClass, il pourrait remplacer le vôtre ou vice versa, ce qui provoque des problèmes.

Le "wrapping" conserve tout dans cette fonction. Si vous avez besoin de rendre quelque chose disponible à l'extérieur, vous pouvez l'exposer.

par commentaire:

Vous pouvez accéder à des fonctions et des variables à l'intérieur de l'emballage en les exposant à l'extérieur comme ceci:

var myApp = (function myApp(){ 

    // The constructor for our "class", this will be available from outside because 
    // we will expose it later 

    var myClass = function(){ 
     //code to set up "class" etc 


     // See how we can use private function within myApp 
     privateFunction(); 
    }; 


    // Here we set up the private function, it will not be available outside myApp 
    // because will will not expose it 
    var privateFunction = function(){ }; 


    // Another public function that we will expose later 
    var otherPublic = function(){}; 

    //now we expose the stuff we want public by returning an object containing 
    // whatever it is we want public, in this case it's just myClass and otherPublic 

    return { myClass: myClass, otherPublic: otherPublic }; 
}()); 

Note dans cet exemple, nous sommes en train d'exposer le constructeur, si vous voulu par exemple de l'objet que vous auriez à les recueillir dans une variable et d'exposer cette variable comme:

var theInstance = new myClass(); 
return { theInstance : theInstance }; 

Il serait maintenant disponible à l'extérieur myApp comme myApp.theInstance

Vous pouvez également utiliser un système d'emballage plus basique:

var myApp = { 

    myClass: function(){ 

     //if we want to call another function in myApp we have to do it like so: 
     myApp.publicFunction(); 
    }, 

    publicFunction: function(){}, 

    someString: "this is a string" 

}; 

Il myApp est juste un littéral d'objet contenant vos fonctions, etc. La principale différence est que tout dans myApp peut être accédé de l'extérieur via myApp.name ou myApp [nom];

+0

puis-je utiliser ce wrapper de l'extérieur? comme: myExample.MyClass.print()? – nemiss

+0

nemiss, j'ai édité ma réponse pour élaborer plus loin par votre question. – MisterMister