Costumo pensar em termos de recursos:
Sintaxe:
Baseado em C ou o que você tem. Java tem uma sintaxe baseada em C. Eu recomendo experimentar algo como Python ou Ruby para tirar sua cabeça da sintaxe e pensar mais em termos de fundamentos de como uma determinada linguagem funciona. Sou da opinião de que nenhuma sintaxe precisa ser mais volumosa que a baseada em C e não tem nenhum problema em criar blocos em torno do espaço em branco.
Compilado vs. interpretado Processo de compilação vs. Interpretado / console:
Tenho muito pouca familiaridade com as preocupações com o tempo de compilação versus o ambiente de tempo de execução, mas percebo que há uma série de preocupações lá em que raramente penso.
Da mesma forma, existem muitas linguagens interpretadas que ainda possuem um processo de compilação para executar dentro de uma máquina virtual, como o Java. Você ainda precisa reconstruir para ver mudanças nas coisas.
E há JavaScript e Python que você pode executar em tempo real, comando por comando em um console em um ambiente ativo. Todos os três podem levar a maneiras muito diferentes de escrever código.
Digitação dinâmica vs. estrita:
Costumo ver os dois como trocas de design. Quando você está em um nível muito mais baixo e o desempenho é crítico, a digitação estática faz muito sentido. Eu nunca entendi essa noção de que um é "mais seguro" do que outro, mas de alguma forma me deparei com uma linguagem plástica / dinâmica, onde você aprende como o sistema de digitação funciona e o que esperar, basicamente. As travessuras de tipo raramente são uma preocupação para mim em JS. De certa forma, a flexibilidade pode tornar as coisas mais robustas, embora seja um toque mais arcano para um desenvolvedor de nível mais Jr., se você não conhece alguns dos buracos na língua.
Escopo em nível de bloco vs. escopo de função vs.?:
O nível de bloco é o mais comum (qualquer coisa entre {} na maioria das linguagens de sintaxe baseadas em c). O escopo do JavaScript é construído em torno de funções (que também são usadas para criar objetos de maneira tão eficaz). Há também uma grande variação no tipo de acesso que você tem do escopo interno para o escopo externo. Não estou familiarizado com outros esquemas de escopo, mas tenho certeza de que eles existem.
POO clássico vs. PO prototípico vs Quase POO (estruturas em C?) Vs Não POO:
Mesmo no OOP baseado em classe, há muito espaço para variação. Se você pode fazer herança múltipla (ew, muito em excesso, ew), definir interfaces, etc ...
Em JavaScript, temos uma espécie de OOP protótipo híbrido atrofiado, em que os objetos são consideravelmente mais simples, altamente mutáveis, mas ainda temos a capacidade de separar a interface das preocupações internas, que IMO é o aspecto importante do encapsulamento.
A questão do POO é que realmente existem muitas coisas que você pode realizar que são essencialmente orientadas para o POO, sem ser tecnicamente OOP. É claro que existem puristas, mas no final do dia, os Padrões de Design buscam certas abstrações que funcionam bem em determinadas situações. Não seja rápido demais para assumir que as idéias de uma linguagem baseada em OOP não têm utilidade em algo mais orientado a procedimentos. E eu não estou falando sobre JavaScript. Não é de todo limitado por sua versão pateta de um paradigma OOP baseado em protótipo.
Funções de primeira classe:
Não tê-los em um idioma é uma coisa difícil para eu desistir. Você pode transmitir funções como se fossem dados para uso em outros contextos. Isso torna os esquemas de manipulação de eventos em particular muito fáceis de implementar, mas também facilita a adaptação do idioma para que funcione da maneira que você deseja. É, mais do que qualquer coisa que eu suspeito, a coisa que fez do JavaScript o sucesso final, apesar de ter sido projetado em duas semanas e de ter a sintaxe aproximada de Java aplicada como um esquema de marketing.
Encerramentos:
Não sei ao certo onde está o debate sobre o Java, mas sei que muitos desenvolvedores de Java estavam clamando por esse recurso há um ou dois anos. Em uma linguagem sem fechamento, quando uma função é fechada, qualquer coisa que seja capaz de referenciar coisas de dentro dessa função não poderá acessá-lo porque foi coletada de lixo. Em um fechamento, o contexto de execução é vinculado de tal forma que, se você é capaz de referenciar coisas dentro dessa função fechada de outro escopo, como em um objeto ou função retornado, basicamente obtém esses vars como estavam quando a função foi fechada. É como bater com o pé na porta da coleta de lixo, embora eu suspeite que tenha sido implementado mais como cópias desses vars transformados em vars locais da entidade de referência.
Rígido / Rigoroso / Seguro vs. Dando a Você Toda a Corda que Você Quer:
Devs JS e Java devs tendem a não se entender e acho que tem muito a ver com as duas linguagens que caem em lados quase opostos desse espectro de design específico. Não quero que você me proteja de mim ou dos outros desenvolvedores da minha equipe. Quero fazer muito mais em muito menos código e fazer tudo de maneiras muito diferentes (mas consistentes para um determinado domínio), dependendo da situação. Há absolutamente trocas entre os dois e muitos idiomas tendem a cair mais no meio.