I tend to think in terms of features:
C-Based or what-have-you. Java has a C-based syntax. I highly recommend trying out something like Python or Ruby to get your head out of the syntax and thinking more in terms of fundamentals of how a given language works. I'm of the opinion that no syntax needs to get bulkier than C-based and have no problem building blocks around white-space.
Compiled vs. interpreted w. Build-Process vs. Interpreted/Console:
I have very little familiarity with compile time vs. run-time environment concerns but I get that there's a whole bag of concerns there that I rarely think about.
Likewise there are plenty of interpreted languages that still have something of a compile-ish process for running inside a virtual machine like Java does. You still have to rebuild to see changes to things.
Dynamic vs. Strict typing:
I tend to see the two as design tradeoffs. When you are at a much lower level and performance is critical, static typing makes a lot of sense. I've never understood this notion of one being "safer" than another somehow but I came up in a very plastic/dynamic language where you just learn how the typing system works and what to expect, basically. Type shenanigans are rarely a concern for me in JS. In some ways the flexibility can make things more robust, although admittedly a touch more arcane for a more Jr. level dev if you don't know about some of the pot-holes in the language.
Block-Level Scope vs. Function Scope vs. ?:
Classical OOP vs. Prototypal OOP vs Almost-OOP(structs in C?) vs Non-OOP:
Even in class-based OOP there is a great deal of room for variation. Whether you can do multiple inheritance (ew, well in excess, ew), define interfaces, etc...
I'm not sure where the debate is at for Java, but I know a lot of Java devs were clamoring for this feature a year or two ago. In a non-closure language, when a function closes, anything that is somehow able to reference stuff from inside that function won't be able to access it because it was garbage collected. In a closure, execution context is bound such that if you're able to reference stuff inside that closed function from another scope like in a returned object or function you basically get those vars as they were when the function closed. It's like a jamming your foot in the door of garbage collection, although I suspect it's implemented more like copies of those vars made into local vars of the referring entity.
Rigid/Strict/Safe vs. Giving You all The Rope You Want:
JS devs and Java devs tend to not understand each other at all and I think it has a lot to do with the two languages falling on near-opposite sides of this particular design spectrum. I don't want you to protect me from myself or from the other devs on my team. I want to do a lot more in a lot less code and to do it all in very different (but consistent for a given domain) ways depending on the situation. There are absolutely tradeoffs to both and a lot of languages tend to fall more in the middle.