Best practice Javascript orientate agli oggetti? [chiuso]


251

Mi trovo a codificare un grande progetto in Javascript. Ricordo che l'ultimo è stato piuttosto un'avventura perché hacky JS può rapidamente diventare illeggibile e voglio che questo codice sia pulito.

Bene, sto usando oggetti per costruire una libreria, ma ci sono diversi modi per definire le cose in JS, implicando importanti conseguenze nella portata, nella gestione della memoria, nello spazio dei nomi, ecc. EG:

  • usando varo no;
  • definire le cose nel file, o in uno (function(){...})()stile jquery;
  • usando thiso no;
  • usando function myname()o myname = function();
  • definire metodi nel corpo dell'oggetto o usando "prototipo";
  • eccetera.

Quindi quali sono davvero le migliori pratiche quando si codifica in OO in JS?

Spiegazioni accademiche davvero attese qui. Link a libri calorosamente benvenuti, purché si tratti di qualità e robustezza.

MODIFICARE :

Ho ricevuto alcune letture, ma sono ancora molto interessato alle risposte alle domande precedenti e alle migliori pratiche.


2
Forse "oggetto orientato" nel titolo dovrebbe essere sostituito a "moderno".
viam0Zah,

43
Hmmm, 79 voti positivi, 82 voti favorevoli, 91 voti positivi sulla risposta ... ma questo è stato chiuso perché non costruttivo ... perché ??
Brett Rossier,

1
Ho scritto una semplice classe di porting di funzionalità C ++ OOP su javascript con una sintassi semplice e naturale. Vedere la mia risposta qui: stackoverflow.com/a/18239463/1115652

14
Questo tipo di domanda viene sempre chiusa. Capisco le ragioni di ciò, ma poiché sono domande importanti e sempre popolari (e poiché le trovo sempre quando ho una domanda simile), mi chiedo se qualcuno può indirizzarci nella sede corretta per porle?
KP MacGregor,

2
@BrettRossier A che serve il potere se non lo maneggi? SO è la dimostrazione dal vivo di come funziona un ordine democratico di beccheggio. Sicuramente alcuni psicologi lo stanno esaminando ...

Risposte:


288

Usando `var` o no

È necessario introdurre qualsiasi variabile con l' varistruzione, altrimenti si arriva all'ambito globale.

Vale la pena ricordare che in modalità rigida ( "use strict";) vengono generati assegnazioni di variabili non dichiarateReferenceError .

Attualmente JavaScript non ha un ambito di blocco. La scuola di Crockford ti insegna a mettere le dichiarazioni var all'inizio del corpo della funzione , mentre la Guida allo stile di Dojo legge che tutte le variabili dovrebbero essere dichiarate nel più piccolo ambito possibile . (La letdichiarazione e la definizione introdotte in JavaScript 1.7 non fanno parte dello standard ECMAScript.)

È buona norma associare le proprietà degli oggetti utilizzati regolarmente alle variabili locali poiché è più veloce che cercare l'intera catena dell'ambito. (Vedi Ottimizzare JavaScript per prestazioni estreme e basso consumo di memoria .)

Definire le cose nel file o in un ((function () {...}) () `

Se non hai bisogno di raggiungere i tuoi oggetti al di fuori del tuo codice, puoi racchiudere l'intero codice in un'espressione di funzione - si chiama modello del modulo. Presenta vantaggi prestazionali e consente inoltre di minimizzare e oscurare il codice ad alto livello. Puoi anche assicurarti che non inquinerà lo spazio dei nomi globale. Le funzioni di avvolgimento in JavaScript consentono inoltre di aggiungere comportamenti orientati all'aspetto. Ben Cherry ha un articolo approfondito sul modello di modulo .

Usando `this` o no

Se usi l'ereditarietà pseudo-classica in JavaScript, difficilmente puoi evitare di usarla this. È una questione di gusti quale modello di eredità usi. Per altri casi, consulta l'articolo di Peter Michaux sui widget JavaScript senza "questo" .

Usando `function myname ()` o `myname = function ();`

function myname()è una dichiarazione di funzione ed myname = function();è un'espressione di funzione assegnata alla variabile myname. Quest'ultimo modulo indica che le funzioni sono oggetti di prima classe e puoi farci qualsiasi cosa, come con una variabile. L'unica differenza tra loro è che tutte le dichiarazioni di funzioni sono sollevate al di sopra dell'ambito di applicazione, il che può avere importanza in alcuni casi. Altrimenti sono uguali. function foo()è una forma abbreviata. Ulteriori dettagli sul sollevamento sono disponibili nell'articolo Scoping e sollevamento di JavaScript .

Definire metodi nel corpo dell'oggetto o usare "prototipo"

Tocca a voi. JavaScript ha quattro modelli di creazione di oggetti: pseudo-classico, prototipico, funzionale e parti ( Crockford, 2008 ). Ognuno ha i suoi pro e contro, vedere Crockford nei suoi discorsi video o ottenere il suo libro The Good Parts come Anon ha già suggerito .

Frameworks

Ti suggerisco di raccogliere alcuni framework JavaScript, studiare le loro convenzioni e il loro stile e trovare le pratiche e i modelli più adatti a te. Ad esempio, Dojo Toolkit fornisce un solido framework per scrivere codice JavaScript orientato agli oggetti che supporta anche l'ereditarietà multipla.

Patterns

Infine, esiste un blog dedicato all'esplorazione di schemi e anti-schemi JavaScript comuni . Controlla anche la domanda Esistono standard di codifica per JavaScript? in Stack Overflow.


1
"JavaScript ha quattro modelli di creazione di oggetti: pseudo-classico, prototipico, funzionale e parti": apprezzerei molto un riassunto dei pro e dei contro qui.
BadHorsie,

2
"La letdichiarazione e la definizione introdotte in JavaScript 1.7 non fanno parte dello standard ECMAScript." Ora fa parte di ES6.
Michał Perłakowski,

13

Scriverò alcune cose che ho letto o messo in applicazione da quando ho posto questa domanda. Quindi le persone che lo leggono non saranno frustrate, poiché la maggior parte delle risposte sono RTMF mascherate (anche se devo ammetterlo, i libri suggeriti SONO buoni).

Uso var

Si suppone che ogni variabile sia già dichiarata nell'ambito più elevato in JS. Quindi, quando mai vuoi una nuova variabile, dichiarala per evitare brutte sorprese come manipolare una var globale senza accorgertene. Pertanto, utilizzare sempre la parola chiave var.

In un oggetto make, var la variabile private. Se vuoi semplicemente dichiarare una variabile pubblica, usa this.my_var = my_valueper farlo.

Metodi di dichiarazione

In JS, sono numerosi modi di dichiarare metodi. Per un programmatore OO, il modo più naturale ed efficiente è utilizzare la sintassi seguente:

All'interno del corpo dell'oggetto

this.methodName = function(param) {

/* bla */

};

C'è un inconveniente: le funzioni interne non saranno in grado di accedere a "questo" a causa del divertente ambito JS. Douglas Crockford consiglia di aggirare questa limitazione utilizzando una variabile locale convenzionale denominata "that". Così diventa

function MyObject() {

    var that = this;

    this.myMethod = function() {

        jQuery.doSomethingCrazy(that.callbackMethod);

    };

};

Non fare affidamento sul fine linea automatico

JS prova ad aggiungere automaticamente ;alla fine della riga se lo dimentichi. Non fare affidamento su questo comportamento, poiché otterrai errori che sono un casino per il debug.


8

Prima di tutto dovresti leggere la programmazione basata su prototipi in modo da sapere con che tipo di bestia hai a che fare e quindi dare un'occhiata alla guida di stile JavaScript alla pagina MDC e JavaScript a MDC . Trovo anche meglio forzare la qualità del codice con uno strumento, ad es. Lint JavaScript o altre varianti.

Le migliori pratiche con OO sembrano più come se volessi trovare modelli che concentrarti sulla qualità del codice, quindi guarda la ricerca di Google: schemi javascript e schemi jQuery .



5

Mi sento spesso l'unico ragazzo qui che usa MooTools per il mio javascript.

È l'acronimo di M y O bject O riented Tools, mootools.

Mi piace molto la loro opinione su OOP in javascript. Puoi anche usare la loro implementazione di classe insieme a jquery, quindi non devi abbandonare jquery (anche se i mootools fanno tutto allo stesso modo).

Ad ogni modo, dai una buona lettura al primo link e vedi cosa ne pensi, il secondo link è ai documenti di mootools.

MooTools ed ereditarietà

Classi MooTools


Non credo che provare a piegare una lingua per adattarla al tuo vecchio habbit sia una buona cosa. È come questa gente in C, usando # per sostituire fa sembrare fortran, oppure. Penso che dovresti provare ad imparare il modo in cui funziona la lingua (e le sue migliori praticheà, e usarlo nel modo che non ti disturba troppo. Ma non cambiarlo, davvero.
e-satis

2
Penso che il sistema di oggetti MooTools sia piuttosto elegante e mi aiuta davvero a mantenere il mio codice organizzato / incapsulato.
awesomo,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.