NodeJS中的JavaScript OOP:怎么样? [英] JavaScript OOP in NodeJS: how?

查看:82
本文介绍了NodeJS中的JavaScript OOP:怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我习惯于Java中的经典OOP。

I am used to the classical OOP as in Java.

使用NodeJS在JavaScript中进行OOP的最佳做法是什么?

What are the best practices to do OOP in JavaScript using NodeJS?

每个类都是 module.export 的文件?

如何创建类?

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

vs。 (我甚至不确定它是否正确)

vs. (I am not even sure it is correct)

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

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

vs。

this.Class = function() {}

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

...

继承如何工作?

是否有特定的实施模块NodeJS中的OOP?

Are there specific modules for implementing OOP in NodeJS?

我找到了一千种不同的方法来创造类似于OOP的东西..但我不知道最常用/实用/干净的方式是什么。

I am finding a thousand different ways to create things that resemble OOP.. but I have no clue what is the most used/practical/clean way.

奖金问题:与MongooseJS一起使用的建议OOP风格是什么? (MongooseJS文档可以被视为一个类和一个用作实例的模型吗?)

Bonus question: what is the suggested "OOP style" to use with MongooseJS? (can a MongooseJS document be seen as a Class and a model used as an instance?)

编辑

以下是 JsFiddle 中的示例,请提供反馈。

here is an example in JsFiddle please provide 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)


推荐答案

这是一个开箱即用的示例。如果你想减少hacky,你应该使用继承库等。

This is an example that works out of the box. If you want less "hacky", you should use inheritance library or such.

好吧,你会写一个文件animal.js:

Well in a file animal.js you would write:

var method = Animal.prototype;

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

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

module.exports = Animal;

在其他文件中使用它:

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

var john = new Animal(3);

如果你想要一个子类,那么在mouse.js中:

If you want a "sub class" then inside 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;

此外,您可以考虑方法借用而不是垂直继承。您不需要从类继承就可以在类上使用它的方法。例如:

Also you can consider "Method borrowing" instead of vertical inheritance. You don't need to inherit from a "class" to use its method on your class. For instance:

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

 }

 method.add = Array.prototype.push;

 ...

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

这篇关于NodeJS中的JavaScript OOP:怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆