it-swarm.com.de

JavaScript OOP in NodeJS: wie?

Ich bin an das klassische OOP wie in Java gewöhnt.

Was sind die besten Methoden, um OOP in JavaScript mit NodeJS zu tun?

Jede Klasse ist eine Datei mit module.export?

Wie erstelle ich Klassen?

this.Class = function() {
    //constructor?
    var privateField = ""
    this.publicField = ""
    var privateMethod = function() {}
    this.publicMethod = function() {} 
}

(Ich bin mir nicht mal sicher, ob es richtig ist)

this.Class = {
    privateField: ""
    , privateMethod: function() {}

    , return {
        publicField: ""
        publicMethod: function() {}
    }
}

vs.

this.Class = function() {}

this.Class.prototype.method = function(){}

...

Wie würde die Vererbung funktionieren?

Gibt es spezielle Module für die Implementierung von OOP in NodeJS?

Ich finde tausend verschiedene Wege, um Dinge zu erschaffen, die OOP ähneln. Aber ich habe keine Ahnung, was der am meisten verwendete/praktische/saubere Weg ist.

Bonusfrage : Was ist der empfohlene "OOP-Stil" für MongooseJS? (Kann ein MongooseJS-Dokument als Klasse angesehen und ein Modell als Instanz verwendet werden?)

[~ # ~] edit [~ # ~]

hier ist ein Beispiel in JsFiddle Bitte geben Sie Feedback.

//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)
102
fusio

Dies ist ein Beispiel, das sofort funktioniert. Wenn Sie weniger "hacky" wollen, sollten Sie die Vererbungsbibliothek oder eine solche verwenden.

Nun, in einer Datei animal.js würden Sie schreiben:

var method = Animal.prototype;

function Animal(age) {
    this._age = age;
}

method.getAge = function() {
    return this._age;
};

module.exports = Animal;

So verwenden Sie es in einer anderen Datei:

var Animal = require("./animal.js");

var john = new Animal(3);

Wenn Sie eine "Unterklasse" wollen, dann in mouse.js:

var _super = require("./animal.js").prototype,
    method = Mouse.prototype = Object.create( _super );

method.constructor = Mouse;

function Mouse() {
    _super.constructor.apply( this, arguments );
}
//Pointless override to show super calls
//note that for performance (e.g. inlining the below is impossible)
//you should do
//method.$getAge = _super.getAge;
//and then use this.$getAge() instead of super()
method.getAge = function() {
    return _super.getAge.call(this);
};

module.exports = Mouse;

Sie können statt der vertikalen Vererbung auch die Methode "Ausleihen" in Betracht ziehen. Sie müssen nicht von einer "Klasse" erben, um ihre Methode für Ihre Klasse zu verwenden. Zum Beispiel:

 var method = List.prototype;
 function List() {

 }

 method.add = Array.prototype.Push;

 ...

 var a = new List();
 a.add(3);
 console.log(a[0]) //3;
111
Esailija

Da die Community von Node.js sicherstellt, dass neue Funktionen aus der JavaScript ECMA-262-Spezifikation den Entwicklern von Node.js rechtzeitig zur Verfügung gestellt werden.

Sie können sich JavaScript-Klassen ansehen . MDN-Link zu JS-Klassen In den JavaScript-Klassen von ECMAScript 6 wurde eine Methode eingeführt, mit der sich Konzepte in JavaScript leichter modellieren lassen OOP).

Hinweis : JS-Klassen funktionieren nur im strengen Modus .

Unten ist ein Skelett der Klasse, Vererbung in Node.js geschrieben (Verwendete Node.js Version v5.0.0 )

Klassendeklarationen:

'use strict'; 
class Animal{

 constructor(name){
    this.name = name ;
 }

 print(){
    console.log('Name is :'+ this.name);
 }
}

var a1 = new Animal('Dog');

Vererbung:

'use strict';
class Base{

 constructor(){
 }
 // methods definitions go here
}

class Child extends Base{
 // methods definitions go here
 print(){ 
 }
}

var childObj = new Child();
41
Piyush Sagar

Ich schlage vor, den inherits -Helfer zu verwenden, der mit dem Standardmodul util geliefert wird: http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor

Es gibt ein Beispiel für die Verwendung auf der verlinkten Seite.

14
badsyntax

Dies ist das beste Video zu objektorientiertem JavaScript im Internet:

Der definitive Leitfaden für objektorientiertes JavaScript

Beobachten Sie von Anfang bis Ende !!

Grundsätzlich ist Javascript eine Prototyp-basierte Sprache, die sich deutlich von den Klassen in Java, C++, C # und anderen beliebten Freunden unterscheidet. Das Video erklärt die Kernkonzepte weitaus besser als jede Antwort hier.

Mit ES6 (veröffentlicht 2015) haben wir ein Schlüsselwort "class", mit dem wir Javascript "classes" wie mit Java, C++, C #, Swift usw. verwenden können.

Screenshot aus dem Video, in dem gezeigt wird, wie eine Javascript-Klasse/Unterklasse geschrieben und instanziiert wird: enter image description here

9
etayluz

In der Javascript-Community argumentieren viele Leute, dass OOP nicht verwendet werden sollte, da das Prototypmodell keine strengen und robusten OOP= nativ zulässt Ich denke nicht, dass OOP eine Frage der Sprache ist, sondern eine Frage der Architektur.

Wenn Sie ein wirklich starkes OOP in Javascript/Node verwenden möchten, können Sie sich das Open-Source-Framework mit vollem Stapel ansehen Danf . Es bietet alle erforderlichen Funktionen für einen starken OOP Code (Klassen, Interfaces, Vererbung, Abhängigkeitsinjektion, ...). Außerdem können Sie dieselben Klassen sowohl auf dem Server (Knoten) als auch auf dem Client (Browser) verwenden Außerdem können Sie Ihre eigenen Danf-Module codieren und dank Npm mit anderen teilen.

4
Gnucki