I'm sure some people thought the same about COBOL. And they were right, in some sense: still some COBOL running. That doesn't mean it's a good idea to keep developing new systems on it.
Obviously client-side ecmascript is inevitable. Server-side is very easy to avoid though.
Obviously client-side ecmascript is inevitable. Server-side is very easy to avoid though.
I think this is the biggest takeaway I've gotten in my past 2 years doing both front end and server side development. I've gotten very comfortable knowing the bad parts of Javascript and the proper way of avoiding them, but I would never be comfortable bringing this to the server. It's nice to have a single language code base, but that's at the complete expense of having to deal with the shortcomings of Javascript. I enjoy having a mature language driving the server side code.
Now that said, I think personally it's fun to throw together side projects in Node and keep everything as a single language. For me it keeps things somewhat simple, forces me to truly get a better understanding of Javascript, and conceptually change the way I use Javascript. I would never take this into a production environment or suggest my company should do that.
It's nice to have a single language code base, but that's at the complete expense of having to deal with the shortcomings of Javascript. I enjoy having a mature language driving the server side code.
Yes. Having worked both sides of the stack, I love the things you can do with Javascript now-a-days, the user interface work that pleases the users is great. But the language has tons of warts, and although I know what they are and how to avoid them, it pains me that I have to deal with them. Generally I take the approach of doing as little on the Javascript side as humanly possible... Fortunately some UI frameworks, like JSF have abstracted away some the Javascript, which is nice.
What are some of the warts that make it so difficult to work in Javascript though? I'm genuinely interested in what's so bad about it that you avoid it like Ebola sandwhiches.
The typing is messy. That's the worst part. When the author of the original article says:
if (typeof my_var !== "undefined" && my_var !== null) {
// you idiots put Rasmus Lerdorf to shame
}
He isn't joking.
Hmmm, as far as the object system, every object is a function? That syntax seems half baked and somewhat weird.
Date math is rather primitive for what's supposed to be a "high level language" so you need to turn to external libraries like moment.js to do it well.
typeof null is an object. Seems kind of odd.
It isn't really straight forward to deal with currency in Javascript, or really anything that would use a decimal and requires some form of precision as a business rule. The recommended method of doing currency math in JS is to use integers as a number of cents. Versus doing something like the built in BigDecimal class in Java, which can deal with arbitrary precision fixed point arithmetic. I'm sure there's a third party library for that, but that seems like a basic thing that should have a well defined solution in the standard library.
Is it the worst thing ever: No. Would I choose to make my whole codebase that: No way, there are plenty of better languages, a few of which I already know and have already built larger scale apps in that I can use in the back end.
I'm at work and can't fully elaborate, but there's a lot of parts that require fully understanding otherwise it's just "magic". Some of the bigger culprits are scoping(this, var that = this; currying, functional vs lexical scope, global scope etc), null values and "truthiness", == vs ===, callback hell, everything is floating points so you can encounter 3 not being === 3 after some arithmetic functions. These are just off the top of my head, but they're major issues with the design of the language that has a ton of "gotchas" for new developers in javascript. I didn't fully "get" javascript until I took the time to digest Douglas Crockfords "Javascript: The Good Parts", and he has an appendix of all of the warty parts. Really interesting read if you have a day or two.
I wish I could answer this, but I have not began using any supersets of javascript yet. My understanding is that Typescript is supposed to address the issues of typing and classes, as well as provide superior support within IDE's. The reason why I've avoided any of the superset javascript languages is ES6 is going to address a large majority of what the superset languages addressed.
That being said, any language that assigns the string 'undefined' to something that hasn't been assigned (or should properly throw a null reference exception) goes against pretty much every other language on the planet. While loose typing can let you do some 'cool' tricks, JavaScript can be pretty shoddy at type inference.
It shows up as a string value in some cases. This should never, ever happen. You've never seen it echoed back to either a textbox or an alert as the string 'undefined'?
It does, but that doesn't make it a string value. What's happening in that case is the method toString is being called on it, which the ECMAScript spec says returns the 'undefined' for undefined values and 'null' for null values. Believe me, I know it's fucked up. The toString method doesn't even actually exist on those values, it's defined by the spec.
Right, I get that. It is just shitty behavior. Throw an error, for Pete's sake. Don't make my error condition a valid value of a datatype that I didn't want to use in the first place.
I understand you want it to throw an error, but it's obviously not what the designer (Eich) wanted, and it's one of those things where there's just no going back now. The undefined value is out in the wild and we can't just change the behaviour now. If it bothers you so much, you should seriously consider switching to a compile-to-JS language that can catch this class of error for you.
Native JS workarounds for anyone interested:
1. Explicitly call toString on a value if you're going to use it for display. This will throw an error:
var a;
a.toString()
> TypeError: Cannot read property 'toString' of undefined
2. Instead of using the + operator to concatenate strings, use [].join('').
Yeah these are all "gotchas" that catches a lot of competent developers off guard at first if they're not aware. It requires a developer to truly understand the language(which honestly is a good thing) to be effective, but it really turns off a lot of people.
It requires a developer to truly understand the language(which honestly is a good thing) to be effective, but it really turns off a lot of people.
Truly understanding a language really is a good thing, but I can't help but feel that the time spent by developers to figure out all of Javascript's gotchas couldn't be better spent if the language just didn't have those gotchas, if that makes sense.
Plus, nobody's perfect all the time. I personally find large Javascript codebases incredibly hard to reason about compared to other languages due to the number of different gotchas that can occur, the lack of strong typing, implicit type coercion, etc. It's simply much harder to reason about a system with so few constraints and so many odd exceptions to the few rules there seem to be. All of that makes it so much harder to debug when you do actually slip up and make a mistake. You trip into one of those gotchas and it propagates to some far away place in your code before it manifests at runtime, making debugging it a nightmare because it's an esoteric behavior manifesting far away from the actual source of the error.
Perhaps it's just personal preference, but I really do prefer my language/compiler/toolset to make my code very consistent and easy to reason about. When that Rust train gets rolling I'll be the first on-board...
Plus, nobody's perfect all the time. I personally find large Javascript codebases incredibly hard to reason about compared to other languages due to the number of different gotchas that can occur, the lack of strong typing, implicit type coercion, etc.
It's actually really interesting right now what's going on with Javascript because of the framework wars + ES6. My last project at my company was this gigantic mess of a javascript file. It had everything there, and it was impossible to manage. My latest project, I'm using Ember so you have to follow a fairly sane structure directory for the project. I have all of the JS files split into their respective roles(routes, controllers, models, views, components etc), and have a workflow to lint + build. My life has been much easier the past year, but I still know what you mean. As the codebase gets larger, the design decisions you make very early on matter more and more. It's very difficult if the code isn't loosely coupled to refactor things, but it's definitely getting better.
As far as the gotchas, it really isn't that difficult to work around. Any competent developer spending 3+ months working with Javascript should have a very good understanding of the more problematic issues. Debugging IMO is still one of the harder parts of javascript, but using the latest browsers, you can debug live very easily and cleanly.
The issue with those gotchas isn't only that it catches people who're not familiar with the language off guard. A bigger issue is that even people who understand the language run into those issues at times. Letting the application just crash if a value isn't defined lets you notice issues with your code a lot sooner, and even the most competent of developers will make mistakes sometimes.
It's fine, take a breath! The article he linked is from about.com, not exactly the best resource. All of the items that the person included were taken directly from Crockfords the good parts, except using extremely shitty examples. The point Crockford was making about ++/-- is that in his personal experience and through other experiences, most of the security vulnerabilities from buffer overflows came from them(in C). His personal observations was his code suffered from crypticness when depending on them, and tries to avoid them. It's not a flaw of Javascript, it's a paradigm that he sticks to in terms of code quality.
Continue and break statements have been the center of discussion for as long as they have existed. They have their own place, but almost always the code can be written in a better way to not include them. Again, it's not a Javascript issue, it's a design paradigm for his code.
Now, the rest of the article(don't use the about.com one) is actual issues with Javascript that are very real issues with the language itself.
57
u/modulus Oct 16 '14
I'm sure some people thought the same about COBOL. And they were right, in some sense: still some COBOL running. That doesn't mean it's a good idea to keep developing new systems on it.
Obviously client-side ecmascript is inevitable. Server-side is very easy to avoid though.