Je suis habitué à la POO classique comme en Java.
Quelles sont les meilleures pratiques pour effectuer la POO en JavaScript à l'aide de NodeJS?
Chaque classe est un fichier avec module.export
?
Comment créer des classes?
this.Class = function() {
//constructor?
var privateField = ""
this.publicField = ""
var privateMethod = function() {}
this.publicMethod = function() {}
}
vs. (je ne suis même pas sûr que ce soit correct)
this.Class = {
privateField: ""
, privateMethod: function() {}
, return {
publicField: ""
publicMethod: function() {}
}
}
contre.
this.Class = function() {}
this.Class.prototype.method = function(){}
...
Comment fonctionnerait l'héritage?
Existe-t-il des modules spécifiques pour implémenter la POO dans NodeJS?
Je trouve mille façons différentes de créer des choses qui ressemblent à la POO ... mais je n'ai aucune idée de la manière la plus utilisée / pratique / propre.
Question bonus : quel est le "style POO" suggéré à utiliser avec MongooseJS? (un document MongooseJS peut-il être vu comme une classe et un modèle utilisé comme une instance?)
ÉDITER
voici un exemple dans JsFiddle s'il vous plaît fournir des commentaires.
//http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/
function inheritPrototype(childObject, parentObject) {
var copyOfParent = Object.create(parentObject.prototype)
copyOfParent.constructor = childObject
childObject.prototype = copyOfParent
}
//example
function Canvas (id) {
this.id = id
this.shapes = {} //instead of array?
console.log("Canvas constructor called "+id)
}
Canvas.prototype = {
constructor: Canvas
, getId: function() {
return this.id
}
, getShape: function(shapeId) {
return this.shapes[shapeId]
}
, getShapes: function() {
return this.shapes
}
, addShape: function (shape) {
this.shapes[shape.getId()] = shape
}
, removeShape: function (shapeId) {
var shape = this.shapes[shapeId]
if (shape)
delete this.shapes[shapeId]
return shape
}
}
function Shape(id) {
this.id = id
this.size = { width: 0, height: 0 }
console.log("Shape constructor called "+id)
}
Shape.prototype = {
constructor: Shape
, getId: function() {
return this.id
}
, getSize: function() {
return this.size
}
, setSize: function (size) {
this.size = size
}
}
//inheritance
function Square(id, otherSuff) {
Shape.call(this, id) //same as Shape.prototype.constructor.apply( this, arguments ); ?
this.stuff = otherSuff
console.log("Square constructor called "+id)
}
inheritPrototype(Square, Shape)
Square.prototype.getSize = function() { //override
return this.size.width
}
function ComplexShape(id) {
Shape.call(this, id)
this.frame = null
console.log("ComplexShape constructor called "+id)
}
inheritPrototype(ComplexShape, Shape)
ComplexShape.prototype.getFrame = function() {
return this.frame
}
ComplexShape.prototype.setFrame = function(frame) {
this.frame = frame
}
function Frame(id) {
this.id = id
this.length = 0
}
Frame.prototype = {
constructor: Frame
, getId: function() {
return this.id
}
, getLength: function() {
return this.length
}
, setLength: function (length) {
this.length = length
}
}
/////run
var aCanvas = new Canvas("c1")
var anotherCanvas = new Canvas("c2")
console.log("aCanvas: "+ aCanvas.getId())
var aSquare = new Square("s1", {})
aSquare.setSize({ width: 100, height: 100})
console.log("square overridden size: "+aSquare.getSize())
var aComplexShape = new ComplexShape("supercomplex")
var aFrame = new Frame("f1")
aComplexShape.setFrame(aFrame)
console.log(aComplexShape.getFrame())
aCanvas.addShape(aSquare)
aCanvas.addShape(aComplexShape)
console.log("Shapes in aCanvas: "+Object.keys(aCanvas.getShapes()).length)
anotherCanvas.addShape(aCanvas.removeShape("supercomplex"))
console.log("Shapes in aCanvas: "+Object.keys(aCanvas.getShapes()).length)
console.log("Shapes in anotherCanvas: "+Object.keys(anotherCanvas.getShapes()).length)
console.log(aSquare instanceof Shape)
console.log(aComplexShape instanceof Shape)
prototype
chaîne . Et, non, object ne prend pas en charge les membres " privés ". Seules les fermetures peuvent offrir cela, bien que les modules / scripts dans Node.js soient implémentés comme des fermetures.Réponses:
Ceci est un exemple qui fonctionne hors de la boîte. Si vous voulez moins de "hacky", vous devez utiliser une bibliothèque d'héritage ou autre.
Eh bien dans un fichier animal.js vous écririez:
Pour l'utiliser dans un autre fichier:
Si vous voulez une "sous-classe", alors dans mouse.js:
Vous pouvez également envisager «l'emprunt de méthode» au lieu de l'héritage vertical. Vous n'avez pas besoin d'hériter d'une "classe" pour utiliser sa méthode sur votre classe. Par exemple:
la source
Animal.prototype.getAge= function(){}
et simplement ajouter à l'this.getAge = function(){}
intérieurfunction Animal() {}
? La sous-classe semble un peu hacky .. avec la bibliothèque "héritage" vous voulez dire quelque chose commeinherits
suggéré par @badsyntax?inherits(Mouse, Animal);
ça nettoie un peu l'héritage mis en place. La différence est que vous créez une nouvelle identité de fonction pour chaque objet instancié au lieu de partager une fonction. Si vous avez 10 souris, vous avez créé 10 identités de fonction (c'est seulement parce que la souris a une méthode, si elle avait 10 méthodes, 10 souris créeraient 100 identités de fonction, votre serveur gaspillerait rapidement la plupart de son CPU sur GC: P) , même si vous ne les utiliserez pour rien. La langue n'a pas assez de pouvoir expressif pour optimiser cela actuellement.Mouse.prototype = new Animal()
.. comment cela se compare-t-il à votre exemple? (par exemple, qu'est-ce que c'estObject.create()
?)La communauté Node.js s'assure que les nouvelles fonctionnalités de la spécification JavaScript ECMA-262 sont apportées aux développeurs Node.js en temps opportun.
Vous pouvez jeter un œil aux classes JavaScript . Lien MDN vers les classes JS Dans les classes JavaScript ECMAScript 6, cette méthode fournit un moyen plus simple de modéliser des concepts POO en Javascript.
Remarque : les classes JS ne fonctionneront qu'en mode strict .
Voici un squelette de classe, l'héritage écrit en Node.js (Used Node.js Version v5.0.0 )
Déclarations de classe:
Héritage:
la source
Je suggère d'utiliser l'
inherits
assistant fourni avec leutil
module standard : http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructorIl existe un exemple de son utilisation sur la page liée.
la source
Voici la meilleure vidéo sur le JavaScript orienté objet sur Internet:
Le guide définitif du JavaScript orienté objet
Regardez du début à la fin !!
Fondamentalement, Javascript est un langage basé sur un prototype qui est assez différent des classes en Java, C ++, C # et d'autres amis populaires. La vidéo explique les concepts de base bien mieux que n'importe quelle réponse ici.
Avec ES6 (sortie en 2015), nous avons un mot-clé "class" qui nous permet d'utiliser des "classes" Javascript comme nous le ferions avec Java, C ++, C #, Swift, etc.
Capture d'écran de la vidéo montrant comment écrire et instancier une classe / sous-classe Javascript:
la source
Dans la communauté Javascript, beaucoup de gens soutiennent que la POO ne devrait pas être utilisée car le modèle prototype ne permet pas de faire une POO stricte et robuste de manière native. Cependant, je ne pense pas que la POO soit une question de langage mais plutôt une question d'architecture.
Si vous souhaitez utiliser une véritable POO forte en Javascript / Node, vous pouvez jeter un œil au framework open source complet Danf . Il fournit toutes les fonctionnalités nécessaires pour un code POO fort (classes, interfaces, héritage, injection de dépendances, ...). Il vous permet également d'utiliser les mêmes classes sur les côtés serveur (nœud) et client (navigateur). De plus, vous pouvez coder vos propres modules danf et les partager avec n'importe qui grâce à Npm.
la source
Si vous travaillez seul et que vous voulez ce qui se rapproche le plus de la POO comme vous le trouverez en Java, C # ou C ++, consultez la bibliothèque javascript, CrxOop. CrxOop fournit une syntaxe assez familière aux développeurs Java.
Attention, la POO de Java n'est pas la même que celle trouvée dans Javascript. Pour obtenir le même comportement qu'en Java, utilisez les classes de CrxOop, pas les structures de CrxOop, et assurez-vous que toutes vos méthodes sont virtuelles. Un exemple de syntaxe est,
Le code est pur javascript, pas de transpilage. L'exemple est tiré d'un certain nombre d'exemples de la documentation officielle.
la source