JavaScript OOP в NodeJS: как?
я привык к классическому ООП как в Java.
каковы наилучшие методы для ООП в JavaScript с использованием NodeJS?
каждый класс представляет собой файл с module.export
?
как создать классы?
this.Class = function() {
//constructor?
var privateField = ""
this.publicField = ""
var privateMethod = function() {}
this.publicMethod = function() {}
}
и (я даже не уверен, что это правильно)
this.Class = {
privateField: ""
, privateMethod: function() {}
, return {
publicField: ""
publicMethod: function() {}
}
}
и
this.Class = function() {}
this.Class.prototype.method = function(){}
...
как будет работать наследование?
существуют ли конкретные модули для реализации ООП в NodeJS?
Я нахожу тысячи различных способов создания вещей, похожих на ООП.. но я понятия не имею, что является наиболее используемым/практичным/чистым способом.
бонус вопрос: что такое предлагаемый "стиль ООП" для использования с MongooseJS? (можно ли рассматривать документ MongooseJS как класс и модель, используемую в качестве экземпляра?)
редактировать
вот пример JsFiddle пожалуйста, обеспечить обратную связь.
//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)
5 ответов
Это пример, который работает из коробки. Если вы хотите меньше "hacky", вы должны использовать библиотеку наследования или такую.
хорошо в файле животного.js вы напишете:
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);
если вы хотите "подкласс", то внутри мыши.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;
также вы можете рассмотреть "заимствование метода" вместо вертикального наследования. Вам не нужно наследовать от "класса", чтобы использовать его метод в классе. Для пример:
var method = List.prototype;
function List() {
}
method.add = Array.prototype.push;
...
var a = new List();
a.add(3);
console.log(a[0]) //3;
Как Узел.сообщество js гарантирует, что новые функции из спецификации JavaScript ECMA-262 будут доведены до узла.разработчики js своевременно.
Вы можете взглянуть на классы JavaScript. MDN ссылка на классы JS В ECMAScript 6 классов JavaScript введены, этот метод обеспечивает более простой способ моделирования концепций ООП в Javascript.
Примечание : классы JS будут работать только в строгий режим.
Ниже приведен некоторый скелет класса, наследование, написанное в узле.js (используемый узел.с JS версии У5.0.0 )
заявления-класс :
'use strict';
class Animal{
constructor(name){
this.name = name ;
}
print(){
console.log('Name is :'+ this.name);
}
}
var a1 = new Animal('Dog');
наследование :
'use strict';
class Base{
constructor(){
}
// methods definitions go here
}
class Child extends Base{
// methods definitions go here
print(){
}
}
var childObj = new Child();
Я предлагаю использовать inherits
помощник, который поставляется со стандартным util
модуль: http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
есть пример того, как использовать его на связанной странице.
Это лучшее видео об объектно-ориентированном JavaScript в интернете:
окончательное руководство по объектно-ориентированному JavaScript
посмотреть от начала до конца!!
в принципе, Javascript-это прототипу язык, который сильно отличается от классов в Java, C++, C# и других популярных друзей. Видео объясняет основные концепции намного лучше, чем любой ответ здесь.
с ES6 (выпущен 2015) мы получили ключевое слово "class", которое позволяет нам использовать Javascript" classes", как мы бы с Java, C++, C#, Swift и т. д.
скриншот из видео, показывающий, как писать и создавать экземпляр класса/подкласса Javascript:
в сообществе Javascript многие люди утверждают, что ООП не следует использовать, потому что модель прототипа не позволяет делать строгий и надежный ООП изначально. Однако я не думаю, что ООП-это вопрос языка, а скорее вопрос архитектуры.
Если вы хотите использовать реальный сильный ООП в Javascript / Node, вы можете взглянуть на полный стек open source framework Danf. Он предоставляет все необходимые функции для сильного кода ООП (классы, интерфейсы, наследование, зависимость-инъекций ...). Он также позволяет использовать одни и те же классы как на стороне сервера (узла), так и на стороне клиента (браузера). Кроме того, вы можете кодировать свои собственные модули danf и делиться ими с кем угодно благодаря Npm.