There was a time when it was basically bullshit, and I still have that feeling about it but I admit that it's an old way of thinking and harkens back to the days of the early internet and internet browsers.
Hah! Yes. I feel you. I still get a bit of that at times.
JavaScript really has developed over the years. Especially with all the work done on web standards. There have been lots of new useful core APIs added to browsers.
More so, if you learn about the new ES6 features, they've really buffed up the language. It's really starting to feel like a full and proper modern language now. Things that felt fundamental, but were missing for years, have finally been added. Like a proper module system. They've also added a class keyword, so you can design classes much like in other programming languages now. Granted, the language supported similar before, using objects, prototypes, and closures, though it looked much different.
JavaScript is definitely the way to go for modern web games, or even office style apps within the browser. Think Gmail and Google Docs. Heck, you can even build offline web applications now. Bookmark the page, and return to it, even if you're not connected to the internet. Very useful for programming documentation.
Indeed,
closures are very interesting.
C can't have closures, since C doesn't allow nested functions. It allows nested structs and classes, and you can nest those within a function, but you can't nest a function within a function.
Pascal has nested functions. The inner function has access to the local variables of the enclosing function. I had to implement such behaviour in a compiler course before. Very neat, and although not hard, was a bit strange to reason about. Each stack frame has two parent pointers, the dynamic scope and the static scope. That's how you keep track of the enclosing function, even in the case of recursion. However, Pascal does not support calling a nested function after the enclosing function has exited. Hence Pascal also doesn't have closures. Essentially, Pascal still used a stack for the function's activation records (stack frames).
One way to support closures is to make activation records dynamic by storing them on the heap. Less efficient, but more flexible, and allows a function's variables to live past the point at which it returns, allowing any nested functions (perhaps returned to the caller or passed to a global data structure) to still be called and access those variables.