JavaScript procedurale o OOP?

Martedì 9 Giugno 2009 - 09:12

di Gabriele Romanato

Scripting

Per chi proviene, come me, dalla programmazione OOP JavaScript può risultare per alcuni versi traumatico. Mancando di parole riservate come class, extends, private, public e protected ed essendo di fatto un linguaggio “class-free”, JavaScript richiede un notevole sforzo per essere apprezzato come linguaggio OOP, o meglio, come linguaggio per lo meno basato sugli oggetti.

Ho iniziato la mia avventura scrivendo codice procedurale e solo dopo aver studiato a fondo numerosi manuali e tutorial (come JavaScript. The good parts di Douglas Crockford e Professional JavaScript for web developers di Nicholas Zakas, le cui idee sono di fatto confluite nella libreria YUI) sono migrato progressivamente verso un codice OOP.

Sinceramente, anche se riconosco gli indubbi vantaggi di un codice OOP, non mi sento di dover bollare come programmatori di serie B chi in JavaScript assume un approccio procedurale, e questo per diverse ragioni:

  • JavaScript conferisce un immenso potere alla proprietà prototype. Per chi viene da un linguaggio OOP classico, questa proprietà risulta difficile da comprendere, data la sua natura dinamica.
  • La bontà del codice deriva in gran parte dal tipo di algoritmo usato. In tal senso, un algoritmo efficace può rendere un codice procedurale performante quasi quanto un codice OOP.
  • L’adozione di un approccio procedurale o OOP dovrebbe essere stabilita in base al tipo di progetto e alle caratteristiche che vi si vogliono aggiungere. Per esempio, se in un sito l’unico effetto che vogliamo ottenere è quello di avere le righe di tabella con colori alternati, usare un approccio OOP risulterebbe quanto meno ridondante

In sintesi, è sempre bene tenere a mente cosa vogliamo ottenere e come. Al limite, possiamo considerare l’approccio procedurale come propedeutico a quello OOP, ossia come una fase di transizione verso una migliore scrittura del codice. Sicuramente, dividere i due approcci in base ad una superiorità dell’uno sull’altro porterebbe ad una nuova “guerra di religione” in cui non ci sarebbero né vinti né vincitori.

Tags:

Categoria: Scripting | Permalink

Commenti

1

Per il mio progetto in prossima uscita ho costruito un kit di funzioni e classi utili alla creazione di moduli caricati runtime sul browser. I moduli e questo “kit” sono tutti costruiti a classi.

Javascript considera anche gli array un oggetto; tuttavia gli manca la definizione di una classe. Bisogna quindi istanziare un oggetto con metodi/attributi di default e creare una nuova istanza dello stesso. Non si può definire una classe ma definendo un oggetto di default è piu o meno simile.

Esiste poi una funzione che fa tutto questo.

Su javascript è ESSENZIALE un framework (consiglio jquery) se si deve modificare il dom. Per tutto il resto il linguaggio è davvero potente e flessibile.

# - postato da Paolo - 09 Giugno 2009 - 10:14

2

Ultimamente sto usando molto OOP per le mie classi JS, sono molto più pratici per script complessi con diverse funzioni e variabili interne.

# - postato da Eduardo - 09 Giugno 2009 - 10:14

3

Il codice procedurale è meno performante dell’OOP? Non lo sapevo, onestamente…

# - postato da Pino - 09 Giugno 2009 - 10:59

4

@ Pino:

Concordo…

La bontà del codice deriva in gran parte dal tipo di algoritmo usato. In tal senso, un algoritmo efficace può rendere un codice procedurale performante quasi quanto un codice OOP.

Non è dimostrato che OOP sia più performante del metodo procedurale.

# - postato da Paolo - 09 Giugno 2009 - 11:05

5

se scriviamo function pippo(){}; stiamo creando un metodo della super globale (di solito window) … giusto per dire che JS e’ diverso, il procedurale o l’OOP sono concetti “astratti”, tutto e’ basato su scope implicito o esplicito. Aggiungerei in fine che per la tabella con le righe colorate, di certo non serve usare 30Kb di codice ma una manciata di bytes. Le librerie sono anche queste una scelta.

# - postato da andr3a - 09 Giugno 2009 - 12:15

6

Conconrdo con andr3a: le librerie creano dipendenza ed è bene usarle solo dove necessario. Se dovete gestire complesse interfacce allora è un bene usarle altrimenti lasciate stare.

Ricordate comunque che è importante saper fare con codice javascript ciò che si astrae con la libreria. Se non si ha la minima idea di ciò che la libreria sta facendo si rischia di non saper risolvere un eventuale problema che potrebbe presentarsi.

# - postato da Paolo - 09 Giugno 2009 - 12:26

7

Ciao,
il javascript è un linguaggio fortemente orientato alla programmazione funzionale.

L’intento con cui era nato all’interno di netscape era quello di portare le potenzialità di un linguaggio come quello dello scheme all’interno di una sintassi c-like.

Javascript permette di programma in modalità procedurale,orientata agli oggetti e funzionale.

E’ vero non ha classi, ne moduli, ne namespace, ne metodi privati ad esempio.

Ma tutte queste cose possono essere aggiunte grazie alla potenzialità del linguaggio.
Potenzialtà che non hanno nulla da invidiare a linguaggi come c# o java. Anzi posso tranquillamente scrivere che conoscendo il linguaggio da 10 anni Javascript e molto più potente, come sintassi, di questi linguaggi.

Pur avendo una sintassi c-like la sua natura è più vicina a linguaggi come lisp e haskell.

Se provate a studiarvi il codice interno di jquery riconoscerete molte di queste tecniche di programmazione funzionale:

- no side effect
- closure
- monads
- first class functions

ecc. ecc.

vi consiglio di dare un occhio a questa slide di uno dei programmatori di dojotoolkit:

http://alex.dojotoolkit.org/wp....._in_JS.pdf

è molto interessante e anche la liberira functional.js di olive r steele

http://osteele.com/sources/jav.....unctional/

g

# - postato da sasuke - 09 Giugno 2009 - 12:42

8

da leggere…

# - postato da Pino - 09 Giugno 2009 - 17:16

9

@pino

interessante ma ripeto quello che manca oggi è una formazione anche nella programmazione funzionale.

# - postato da sasuke - 09 Giugno 2009 - 18:37

10

provate a vedere quanto tempo righe di codice ci voglio per fare questa espressione funzionale in jquery in modo procedurale.

var arr=$([1,2,4,5,6,3]).map(function() {
returh this>3 ? this : null;
}).get().sort(function(a,b) {
return a-b
});

l’array [1,2,4,5,6,3] viene filtrato per i numeri maggiori di 3 e ordinato e assegnato alla variabile arr.

Tutto questo 5 righe di codice e dichiarando solo una variabile.
Usando un oggetto che utilizziamo tutti i giorni come jquery.
Ed è solo una funzione lambda.

Si potrebbero aprire spaccati molto interessanti su funzioni anonime, closure, monadi e altro ancora…..

La programmazione funzionale si avvicina molto di più al linguaggio naturale e rende più facile scrivere codice.

# - postato da sasuke - 09 Giugno 2009 - 18:42

11

@Gabriele: tanti auguri per la tua nuova avventura!!! :)

@sasuke: sono d’accordo quando dici: “La programmazione funzionale si avvicina molto di più al linguaggio naturale e rende più facile scrivere codice.”
ma non coincide con lo spezzone di codice che hai presentato.
Anche in Perl puoi scrivere su una riga di codice ciò che potresti scriverlo anche in 30, ma non per questo è funzionale, in quanto non autoesplicativa.

Prendi l’espressione tua:

var arr=$([1,2,4,5,6,3]).map(function() {
returh this>3 ? this : null;
}).get().sort(function(a,b) {
return a-b
});

e poi prendi quest’altra forma:

from( [1,2,4,5,6,3] ).where(”item > 3″).orderBy(”previousItem<currentItem”);

Non sarebbe molto più funzionale se fosse così?

QUESTA è programmazione funzionale e già esiste qualcosa di molto simile a quello che ho scritto che è LINQ. ;)

Ciao
Diego

# - postato da Diego La Monica - 09 Giugno 2009 - 20:10

12

@Diego

Ciao Diego hai ragione,
però quella sintassi e nei limiti di javascript e di jquery.
Se parliamo di sintassi esistono linguaggi di programmazione come ruby,groovy, haskell ecc…. che hanno una sintassi molto più chiara e limpida (io adoro molto quella di ruby).

Che javascript possa applicare una sintassi ostica applicata a quando si programma in modo funzionale sono d’accordo, il fatto di dover riutlizzare sempre la keyword function per definire una funzione è pesante, però con l’abitudine è come imparare una nuova lingua. Tanto è vero che tra le varie proposte, sulle modifiche di js, c’è anche quella di sostituire la keyword function con altri simboli.

Cmq in ruby Avrei potuto scrivere cosi allora:

[1,2,35,6,4].select {|item| item >3 }.sort {|a,b| ab }

rendendo il codice molto più leggibile.

E’ vero linq ha preso molto idee dalla programmazione funzionale.

Un esempio interessante che potresti fare è provare a riscrivere lo stesso codice in linq usando delle funzioni anonime invece di usare le stringhe.

# - postato da sasuke - 09 Giugno 2009 - 20:26

13

@Diego:

Ciao Diego,
rileggendo oggi i commenti che ho scritto forse non è specificato chiaramente cosa è la programmazione funzionale, e ci siamo fraintesi sul loro significato.

Per me programmazione funzionale è questa esposta in questo link di wikipedia:

http://it.wikipedia.org/wiki/P.....funzionale

# - postato da sasuke - 10 Giugno 2009 - 10:51

14

non sapevo servisse jQuery per fare quella operazione …

(arr = [1,2,4,5,6,3].filter(
function(i){return i > 3}
)).sort(
function(a,b){return a-b}
);

saluti a tutti i fan di JavaScript (… librerie a parte …)

P.S. Diego, quanto hai scritto vicino a linq lo fai anche col JavaScript … è questo il bello, è così flessibile da permetterti di creare stili sintattici e/o funzionali.

# - postato da andr3a - 10 Giugno 2009 - 16:34

15

@andr3a
ciao Andrea,
con jquery è un esempio che si poteva fare con prototype.

L’esempio che hai fatto tu non gira su tutti i browser.
Explorer 6 e 7 non supporta le estensione filter nel prototype di Array.

Era solo per dimostrare un modo differente di programmazione in js.

# - postato da sasuke - 10 Giugno 2009 - 18:43

16

ah, quindi preferisci 30Kb di libreria per implementare questo … i gusti son gusti.

Array.prototype.filter = function(callback, self){
for(var result = [], length = this.length, i = 0, j = 0, tmp; i < length; ++i){
if((i in this) && callback.call(self, tmp = this[i], i, this))
result[j++] = tmp;
};
return result;
};

direttamente da vice-versa. saluti

# - postato da andr3a - 11 Giugno 2009 - 00:48

17

@Andrea:
SI ok Andrea hai ragione, ma stiamo andando fuori dal contesto della discussione.
Quello su cui discuto io è che la programmazione funzionale è poco discussa e usata in javascript, soprattutto qui in italia molti non sanno cosa sia applicata a js.

Non è una disputa se usare una libreria o gli elementi nativi di un linguaggio.

L’esempio che ho portato io all’inizio con jQuery serviva solo a dimostrare cosa si può fare.

# - postato da sasuke - 11 Giugno 2009 - 08:43

18

… molti qua in italia, ma anche all’estero, pensano che il DOM sia $(”body”) … appunto perchè librerie ai designer, ai programmatori JS che sfruttano anche il funzionale, se necessario, lasciamo il linguaggio e possibilimente senza librerie, grazie.

# - postato da andr3a - 12 Giugno 2009 - 01:01

19

@Andrea:
Ciao Andrea, è vero che avvolte si abbusi delle librerie per programmare, ma di certo manipolare il dom è molto più veloce e agile con jquery o altre piuttosto che usare gli oggetti nativi del DOM.

Guarda semplicemente cosa si può fare con un framework come DojoToolkit.
Ha un set di librerie sterminato

# - postato da sasuke - 12 Giugno 2009 - 10:44

Inserisci il tuo commento:





(puoi usare i seguenti tag HTML per formattare il testo -
a href, b, i, br/, p, strong, em, ul, ol, li, blockquote, pre):

 

Anteprima del commento