Saya sudah terbiasa dengan OOP klasik seperti di Jawa.
Apa praktik terbaik untuk melakukan OOP di JavaScript menggunakan NodeJS?
Setiap Kelas adalah file dengan module.export
?
Bagaimana cara membuat Kelas?
this.Class = function() {
//constructor?
var privateField = ""
this.publicField = ""
var privateMethod = function() {}
this.publicMethod = function() {}
}
vs. (Saya bahkan tidak yakin itu benar)
this.Class = {
privateField: ""
, privateMethod: function() {}
, return {
publicField: ""
publicMethod: function() {}
}
}
vs.
this.Class = function() {}
this.Class.prototype.method = function(){}
...
Bagaimana cara kerja warisan?
Apakah ada modul khusus untuk mengimplementasikan OOP di NodeJS?
Saya menemukan ribuan cara berbeda untuk membuat sesuatu yang menyerupai OOP .. tapi saya tidak tahu cara apa yang paling banyak digunakan / praktis / bersih.
Pertanyaan bonus : apa "gaya OOP" yang disarankan untuk digunakan dengan MongooseJS? (dapatkah dokumen MongooseJS dilihat sebagai Kelas dan model digunakan sebagai instance?)
EDIT
berikut adalah contoh di JsFiddle tolong berikan umpan balik.
//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
rantai . Dan, tidak, objek tidak mendukung anggota " pribadi ". Hanya closure yang bisa menawarkan itu, meskipun modul / skrip di Node.js diimplementasikan sebagai closure.Jawaban:
Ini adalah contoh yang berhasil di luar kotak. Jika Anda ingin lebih sedikit "hacky", Anda harus menggunakan perpustakaan warisan atau semacamnya.
Nah di file animal.js Anda akan menulis:
Untuk menggunakannya di file lain:
Jika Anda menginginkan "subkelas" maka di dalam mouse.js:
Anda juga dapat mempertimbangkan "Peminjaman metode" alih-alih warisan vertikal. Anda tidak perlu mewarisi dari "kelas" untuk menggunakan metodenya di kelas Anda. Misalnya:
sumber
Animal.prototype.getAge= function(){}
dan menambahkanthis.getAge = function(){}
di dalamfunction Animal() {}
? Sub-kelas tampaknya agak hacky .. dengan pustaka "warisan" yang Anda maksud seperti yanginherits
disarankan oleh @badsyntax?inherits(Mouse, Animal);
itu membersihkan warisan set up sedikit. Perbedaannya adalah Anda membuat identitas fungsi baru untuk setiap objek yang dibuat alih-alih berbagi satu fungsi. Jika Anda memiliki 10 mouse, Anda telah membuat 10 identitas fungsi (itu hanya karena mouse memiliki satu metode, jika memiliki 10 metode, 10 mouse akan membuat 100 identitas fungsi, server Anda akan dengan cepat membuang sebagian besar CPU-nya pada GC: P) , meskipun Anda tidak akan menggunakannya untuk apa pun. Bahasa tidak memiliki kekuatan ekspresif yang cukup untuk mengoptimalkannya saat ini.Mouse.prototype = new Animal()
.. bagaimana cara membandingkannya dengan contoh Anda? (misalnya apaObject.create()
?)Karena komunitas Node.js memastikan fitur baru dari spesifikasi JavaScript ECMA-262 dibawa ke pengembang Node.js secara tepat waktu.
Anda dapat melihat kelas JavaScript . Link MDN ke kelas JS Dalam ECMAScript 6 kelas JavaScript diperkenalkan, metode ini menyediakan cara yang lebih mudah untuk memodelkan konsep OOP dalam Javascript.
Catatan : Kelas JS hanya akan berfungsi dalam mode ketat .
Di bawah ini adalah beberapa kerangka kelas, warisan ditulis dalam Node.js (Digunakan Node.js Versi v5.0.0 )
Deklarasi kelas:
Warisan :
sumber
Saya menyarankan untuk menggunakan
inherits
helper yang disertakan denganutil
modul standar : http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructorAda contoh bagaimana menggunakannya di halaman tertaut.
sumber
Ini adalah video terbaik tentang JavaScript Berorientasi Objek di internet:
Panduan Definitif untuk JavaScript Berorientasi Objek
Tonton dari awal hingga akhir !!
Pada dasarnya Javascript adalah bahasa berbasis Prototype yang cukup berbeda dengan kelas-kelas di Java, C ++, C #, dan teman-teman populer lainnya. Video tersebut menjelaskan konsep inti jauh lebih baik daripada jawaban apa pun di sini.
Dengan ES6 (dirilis 2015) kami mendapat kata kunci "class" yang memungkinkan kami menggunakan "class" Javascript seperti yang kami lakukan dengan Java, C ++, C #, Swift, dll.
Tangkapan layar dari video yang menunjukkan cara menulis dan membuat instance kelas / subkelas Javascript:
sumber
Dalam komunitas Javascript, banyak orang berpendapat bahwa OOP tidak boleh digunakan karena model prototipe tidak memungkinkan untuk melakukan OOP yang ketat dan kuat secara native. Namun, menurut saya OOP bukan masalah bahasa, melainkan masalah arsitektur.
Jika Anda ingin menggunakan OOP yang sangat kuat di Javascript / Node, Anda dapat melihat kerangka kerja sumber terbuka full-stack Danf . Ini menyediakan semua fitur yang diperlukan untuk kode OOP yang kuat (kelas, antarmuka, warisan, injeksi ketergantungan, ...). Ini juga memungkinkan Anda untuk menggunakan kelas yang sama di kedua sisi server (node) dan klien (browser). Selain itu, Anda dapat membuat kode modul danf Anda sendiri dan membaginya dengan siapa saja berkat Npm.
sumber
Jika Anda bekerja sendiri, dan menginginkan OOP yang paling mendekati seperti yang Anda temukan di Java atau C # atau C ++, lihat pustaka javascript, CrxOop. CrxOop menyediakan sintaks yang cukup familiar bagi pengembang Java.
Hati-hati, OOP Java tidak sama dengan yang ditemukan di Javascript. Untuk mendapatkan perilaku yang sama seperti di Java, gunakan kelas CrxOop, bukan struktur CrxOop, dan pastikan semua metode Anda virtual. Contoh sintaksnya adalah,
Kode ini murni javascript, tidak transpiling. Contoh tersebut diambil dari sejumlah contoh dari dokumentasi resmi.
sumber