2009-05-17 8 views
3

Je fais mon premier projet javascript qui utilise beaucoup les objets. En raison de la façon dont cela fonctionne, presque tous les objets personnalisés sont faits comme ceci:Javascript "classes" (pas de frameworks)

namespaceobj = {}; 
namespaceobj.subobject = {}; 
namespaceobj.subobject.somefunction = function(arg, uments) { 
    // Do Stuff 
} 
namespaceobj.subobject.somedata = 10; 
namespaceobj.othersubject = {}; 
namespaceobj.othersubject.somefunction = function(some, args) { 
    // Do more stuff 
} 
// More subobjects etc. 

Ce qui est bien, comme tous les objets personnalisés ont une seule instance de toute façon (exemples de sous-objets sont l'interface utilisateur, les outils, la données partagées, etc.).

Cependant, j'ai le code vu faire quelque chose comme ça (la syntaxe est probablement faux, ceci est juste de la mémoire de voir un code similaire)

function SomeClass() { 
    this.somedata = 42; 
    this.somefunction = function(a, few, args) { 
     // Do Stuff 
    } 
} 
// More classes and stuff 
// Elsewhere: 
someInstance = new SomeClass(); // AFA I recall, new was optional 
someInstance.somefunction(); 

Quelqu'un pourrait-il expliquer comment les « classes » dans le second ouvrage exemple, et tous les pièges que je pourrais rencontrer en les utilisant.

Répondre

2

Je pense que la syntaxe que vous pensiez ressemble à ceci: -

function SomeClass() { 
    var somedata = 42; 
    this.somefunction = function(a, few, args) { 
    // Do Stuff like:- 
    return somedata + a; 
    } 
} 
// More classes and stuff 
// Elsewhere: 
someInstance = new SomeClass(); // AFA I recall, new was optional 
someInstance.somefunction(15); //returns 57 

La fonction qui est attribué à la unefunction est créé dans un Contexte d'exécution qui résulte lorsqu'une fonction est exécutée (dans ce cas, SomeClass() est exécuté dans le cadre de la nouvelle opération affectée à someInstance). Les fonctions peuvent accéder aux variables qui font partie du contexte d'exécution dans lequel elles sont créées, donc dans ce cas, somedata est une variable à laquelle une fonction a accès.

Cette approche fait effectivement de somedata l'état privé de l'objet, puisque seules les fonctions créées dans le corps de la fonction SomeClass peuvent y accéder.

C'est une simplification excessive, vous devriez envisager la recherche Javascript sans référence à la programmation orientée objet en premier lieu, en apprendre davantage sur les chaînes de portée et chaînes prototypes. Lorsque vous les comprenez, vous pouvez mieux comprendre le nombre d'approches différentes pour implémenter un design OO en Javascript et quelle approche correspond le mieux à vos besoins.

0

Le deuxième exemple est plus clair et les données sont encapsulées. Cela signifie que certaines variables de classe peuvent être calculées en utilisant des variables temporaires. De plus, le deuxième exemple est meilleur pour faire plus d'objets du même type, mais dans votre cas ce n'est pas important. De toute façon, cela ne ralentira pas votre code, donc vous pouvez le faire comme vous voulez.

2

Ceci est un sujet assez important, mais ce que vous voyez est la différence entre notation littérale d'objet (votre premier exemple) et la marque particulière de JavaScript OOP. La principale différence que vous rencontrerez entre les deux est que votre premier exemple a une seule instance statique alors qu'une version révisée de votre second exemple (vous étiez proche) vous permettrait de créer plusieurs instances de la classe.

Je suggère que vous avez lu JavaScript and Object Oriented Programming (OOP):

JavaScript est un excellent langage pour objet écrire des applications Web orientées . Il peut prendre en charge OOP car il prend en charge l'héritage via le prototypage ainsi que les propriétés et méthodes . De nombreux développeurs rejettent JS comme langage OOP approprié car ils sont ainsi utilisés au style de classe C# et Java. Beaucoup de gens ne se rendent pas compte que JavaScript prend en charge l'héritage. Lorsque vous écrivez le code orienté objet, il vous donne instantanément la puissance; vous pouvez écrire du code qui peut être réutilisé et qui est encapsulé.

0

La deuxième forme est peut-être la meilleure forme car elle crée une "classe" qui a de nombreuses fonctions sur son prototype. Quand une nouvelle classe est créée, la nouvelle instance obtient également son jeu de prototypes. Dans l'exemple de classe, les fonctions résident sur le prototype.

Les premiers exemples créent simplement un objet avec beaucoup de fonctions réaffectant les mêmes fonctions à chaque objet chaque fois que cela est nécessaire.

Les prototypes sont préférables car cela signifie que le travail de définition de la "classe" n'est fait qu'une seule fois. Toutes les instances partagent le même prototype - par conséquent, on peut obtenir des constructions puissantes comme ajouter/modifier/supprimer des fonctions et toutes les instances verront le changement. Dans le premier exemple, vous indiquez qu'ils sont tous des objets indépendants où l'on peut changer n'importe quoi sur n'importe quelle instance indépendamment. En fin de compte, tous les objets Javascript sont des hashtables de propriétés et de fonctions. Quand on accède à un objet via "object.something" tout est une valeur incluant des fonctions. Cependant quand on utilise la notation d'invocation de fonction "object.foo (...)" le runtime essaye de trouver un "foo" sur "object". Si le moteur d'exécution ne parvient pas à trouver un "foo" sur "object", il essaiera alors de trouver un "foo" sur le prototype de "object". Cela continue jusqu'à ce que quelque chose soit trouvé ou qu'il ne reste plus de prototypes. Le runtime essayera alors d'invoquer des paramètres de passage de "foo" etc. Naturellement les choses explosent si foo n'est pas une fonction.

Questions connexes