Programmazione orientata agli oggetti in JavaScript. C'è vita senza di essa? [duplicare]

12

Nella nostra azienda abbiamo un codice JavaScript basato su PrototypeJS piuttosto ampio, che stiamo eseguendo il porting su jQuery per diversi motivi (non molto importanti qui). Sto cercando di impostare le linee guida di codifica per rendere / tenere le cose in ordine durante il porting.

Un'osservazione che emerge dall'implementazione basata sul prototipo è che un sacco di codice è scritto in stile OOP (usando Prototype Class.create ), ma il codice non è "orientato agli oggetti" nello spirito. Lo schema generale che ho visto: un "costruttore" che ci si aspetta di chiamare (ma non chiamare due volte, perché il costruttore usa gli ID DOM hardcoded), un mucchio di altre "funzioni" e gestori di eventi, che non ci si aspetta chiama (ma perché non c'è "privato" in JavaScript, non lo sai) e la condivisione dei dati tra tutte queste funzioni tramite this . Visto dal punto di vista del chiamante c'è solo un "callable" e nient'altro.

Sto iniziando a credere che OOP in JavaScript possa e forse dovrebbe essere evitato in molti casi. Almeno per il nostro caso d'uso, che non è l'interfaccia utente di Goole Wave di prossima generazione, ma semplicemente messo: un po 'di miglioramenti basati su AJAX, registrazione di alcuni gestori di eventi qua e là, manipolazioni DOM minori e simili.

  • la funzionalità di cui abbiamo bisogno sembra essere implementabile nel tipico modo jQuery non-OOP, usando la magia di chiusura per ottenere l'incapsulamento e la privateness. Come effetto collaterale, l'efficienza di minification del codice ported è molto migliore.
  • OOP in JavaScript non è tradizionale e confuso se provieni da uno sfondo "tradizionale". Ci sono molti tentativi e schemi per approssimare l'OOP tradizionale, ma IMHO rende le cose ancora più confuse e fragili.
  • Una cosa che mi ha insegnato "JavaScript the good parts" di Crockford è che il vero potere di Javascript risiede negli ambiti delle funzioni e nelle chiusure, tanto meno nei modelli OOP.

Mi chiedo se ci sia un più ampio supporto per questa sensazione che l'OOP in JavaScript non lo tagli davvero come il mantra sacro, come in altre lingue / piattaforme. E, in estensione, che tipo di pattern basati su OOP / chiusura sono molto più preferibili.

    
posta Stefaan 15.05.2013 - 17:52
fonte

3 risposte

4

Le persone tendono ad essere coinvolte in schemi avanzati con OOP. MVC, MVVM, MVVC e ogni altra permutazione di "M", "V" e "C". Non ho mai aperto un progetto js con oltre 20.000 righe e mi sono detto: "Grazie a Dio è in MVC", perché la realtà è che la maggior parte dei progetti con oltre 20.000 linee sarà un pasticcio terribile.

Detto questo, penso ancora che i progetti di grandi dimensioni siano quasi impossibili senza OOP. Per lo meno, la capacità di scrivere oggetti complessi e di archiviarli in file e namespace separati, proteggerli dalle collisioni utilizzando una libreria come dojo, ti farà risparmiare migliaia di ore di doloroso debugging.

"Oh", potresti dire a te stesso: "Bene, posso scrivere gruppi modulari di funzioni in file javascript separati con il meglio di loro. Non ho bisogno di usare OOP." Bene, amico mio- congratulazioni, perché stai già usando efficacemente OOP senza nemmeno saperlo. Quindi, finché questo è il caso, perché non fare un passo avanti e utilizzare le classi reali?

È vero che javascript si basa sul modello del prototipo, tuttavia, la base di OOP è praticamente ereditaria / incapsulante / polimorfismo e javascript può farlo perfettamente bene. Dai un'occhiata a dojo.js.

    
risposta data 15.05.2013 - 18:10
fonte
2

Ritengo importante sottolineare un paio di cose:

  1. OOP e le classi sono due concetti completamente ortogonali. Le classi potrebbero anche funzionare con le strutture / i record (e in effetti lo fanno in alcune lingue). Loro incidentalmente sono utili per costruire tipi specifici di oggetti.
  2. Il controllo accessi è uno strumento utile per l'incapsulamento, ma non è un prerequisito. In JavaScript è comune anteporre i membri "privati" di un oggetto con un trattino basso. Indipendentemente dal fatto che tu scelga di accedervi, è comunque compito tuo decidere. Nella maggior parte delle lingue ci sono alcuni mezzi per superare il controllo degli accessi se lo si desidera veramente. In generale, è una cosa davvero stupida scrivere codice contro qualcosa che non è mai stato esposto consapevolmente da un essere umano per il tuo consumo (e può, ad esempio, cambiare in qualsiasi momento).
  3. OOP non riguarda certamente il modo in cui vengono implementate parti specifiche del tuo sistema (per non parlare della sintassi coinvolta) e vorrei quindi sostenere che l'implementazione non può essere "orientata agli oggetti nello spirito" o meno. OOP è per lo più un meccanismo relativamente intelligente per l'indiretto costruito su incapsulamento e polimorfismo. In sostanza, è poco più di "Tell, Do not Ask".

Se vuoi saltare attraverso i cerchi per trasformare JavaScript in qualcosa che non è, potresti non essere soddisfatto del risultato. Quindi, potresti scegliere uno qualsiasi dei linguaggi disponibili che compilano in JavaScript, ma sono più vicini a ciò che potresti desiderare di avere un linguaggio di programmazione (Haxe, ParenScript, TypeScript, CoffeeScript, ScriptSharp, Dart, Java (tramite GWT), C / C ++ (tramite Emscripten) ... infatti quasi qualsiasi altro linguaggio popolare può essere tradotto in JavaScript con qualità variabile).

Ma se usi JavaScript per quello che è, troverai un linguaggio che consente "class-oids", mixin / tratti, AOP e cosa no. Più spesso, ti renderai conto che limitarti agli idiomi di Java potrebbe non essere la migliore idea. Tuttavia, a volte sono senza dubbio utili.

    
risposta data 15.05.2013 - 19:10
fonte
0

One observation from wading through the prototype based implementation is that a lot of code is written in OOP style (using Prototype's Class.create), but the code is not "object oriented" in spirit. The general pattern I've seen: one "constructor" which you are expected to call (but not call twice, because the constructor uses hardcoded DOM id's), a bunch of other "functions" and event handlers, which you are not expected to call (but the because there is no "private" in JavaScript, you don't know that) and data sharing between all these functions through this. Seen from the caller's point of view there is just one "callable" and nothing else.

Non tutti i progetti Javascript hanno bisogno di OOP. Non andrei lì a meno che non stessimo usando un framework OO esistente come ExtJS. Nel tuo caso, dove sembra che l'unico uso di OOP sia l'uso improprio, penso che dovresti saltare interamente. Dal momento che stai passando a jQuery, basta seguire l'architettura del plugin jQuery. Scrivi plug-in personalizzati quando conveniente.

    
risposta data 15.05.2013 - 19:24
fonte

Leggi altre domande sui tag