Tendo a pensare in termini di funzionalità:
Sintassi:
C-based o what-have-you. Java ha una sintassi basata su C. Consiglio vivamente di provare qualcosa come Python o Ruby per far uscire la testa dalla sintassi e pensare di più in termini di fondamenti di come funziona un determinato linguaggio. Sono dell'opinione che nessuna sintassi debba diventare più voluminosa della C-based e non avere problemi a costruire blocchi di spazio bianco.
Compilato vs. interpretato w. Build-Process vs. Interpreted / Console:
Ho pochissima familiarità con le preoccupazioni relative al tempo di compilazione e al tempo di runtime, ma capisco che ci sono molte preoccupazioni a cui raramente penso.
Allo stesso modo ci sono molti linguaggi interpretati che hanno ancora qualcosa di simile a un processo di compilazione per l'esecuzione all'interno di una macchina virtuale come fa Java. Devi ancora ricostruire per vedere le modifiche alle cose.
E poi c'è JavaScript e Python che puoi eseguire al volo, comando per comando in una console in un ambiente live. Tutti e tre possono portare a modi molto diversi di scrivere il codice.
Digitazione dinamica vs. rigida:
Tendo a vedere i due come compromessi del design. Quando sei ad un livello molto più basso e le prestazioni sono fondamentali, la digitazione statica ha molto senso. Non ho mai capito in qualche modo questa nozione di essere "più sicuro" di un altro, ma mi è venuta in un linguaggio molto plastico / dinamico in cui impari semplicemente come funziona il sistema di digitazione e cosa aspettarti, in pratica. I tipi di shenanigans raramente sono una preoccupazione per me in JS. In un certo senso la flessibilità può rendere le cose più robuste, anche se è vero che un tocco più arcano per un dev di livello Jr. più se non si conoscono alcuni dei buchi nella lingua.
Ambito Block-Level vs. Function Scope vs.?:
Block-Level è il più comune (qualsiasi cosa tra {} nella maggior parte dei linguaggi di sintassi basati su c). L'ambito JavaScript si basa su funzioni (che vengono utilizzate anche per creare oggetti in modo efficace anche oggetti). C'è anche una grande variazione nel tipo di accesso che hai dall'ambito interno a un ambito esterno. Non ho familiarità con altri schemi di scoping ma sono sicuro che esistono.
OOP classico vs. OOP prototipo vs Quasi-OOP (strutture in C?) Vs Non-OOP:
Anche nelle OOP di classe c'è molto spazio per le variazioni. Se puoi fare ereditarietà multipla (ew, beh in eccesso, ew), definire interfacce, ecc ...
In JavaScript abbiamo una sorta di OOP prototipo ibrido stentato in cui gli oggetti sono considerevolmente più semplici, altamente mutabili, ma abbiamo ancora la capacità di separare l'interfaccia dalle preoccupazioni interne, che l'IMO è l'aspetto importante dell'incapsulamento.
La cosa su OOP è che ci sono davvero un sacco di cose che puoi realizzare che sono essenzialmente orientate all'OOP senza essere tecnicamente OOP. Naturalmente ci sono puristi ma alla fine della giornata, i Design Patterns mirano a raggiungere certe astrazioni che funzionano bene in determinate situazioni. Non essere troppo veloce nel ritenere che le idee di un linguaggio basato su OOP non abbiano alcuna utilità in qualcosa che è più orientato alla procedura. E non sto parlando di JavaScript. Non è affatto limitato dalla sua versione sciocca di un paradigma OOP basato su prototipo.
Funzioni di prima classe:
Non avere questi in una lingua è una cosa difficile per me rinunciare. È possibile passare le funzioni come se fossero dati da utilizzare in altri contesti. Ciò rende gli schemi di gestione degli eventi in particolare molto facili da implementare, ma rende anche molto facile adattare la lingua in modo che funzioni nel modo desiderato. È, più di ogni altra cosa, sospetto, ciò che ha fatto di JavaScript il successo che ha avuto il massimo nonostante sia stato progettato in due settimane e sia stata sfruttata la sintassi Java-approssimativa come uno schema di marketing.
chiusure:
Non sono sicuro di dove sia il dibattito su Java, ma so che molti sviluppatori Java hanno chiesto a gran voce questa funzionalità un anno o due fa. In un linguaggio non di chiusura, quando una funzione si chiude, tutto ciò che è in qualche modo in grado di fare riferimento a cose all'interno di quella funzione non sarà in grado di accedervi perché è stato raccolto. In una chiusura, il contesto di esecuzione è vincolato in modo tale che se si è in grado di fare riferimento a elementi all'interno di quella funzione chiusa da un altro ambito come in un oggetto o funzione restituiti, si ottengono sostanzialmente le differenze come erano quando la funzione è stata chiusa. È come un inceppamento del tuo piede nella porta della raccolta dei rifiuti, anche se sospetto che sia implementato più come copie di quei vasi trasformati in vasi locali dell'entità referente.
Rigido / rigoroso / sicuro vs. offrirti tutta la corda che desideri:
Gli sviluppatori JS e Java tendono a non capirsi affatto e penso che abbia molto a che fare con le due lingue che ricadono sui lati quasi opposti di questo particolare spettro del design. Non voglio che tu mi protegga da me stesso o dagli altri sviluppatori della mia squadra. Voglio fare molto di più con molto meno codice e fare tutto in modi molto diversi (ma coerenti per un dato dominio) a seconda della situazione. Ci sono assolutamente dei compromessi per entrambe e molte lingue tendono a cadere di più nel mezzo.