As minimalistic as your comment is, I think it points to the single most important truth about JS: It's practically impossible for human beings to write “good” JS code. The only hope you have is using a sane language with sane concepts that can be compiled down to the JavaScript of the week (ES6, ASM.js, the works...).
I would argue that JS should be handled analogously to Assembler: Good for you if you understand it, but only highly trained field specialists in protective suits dare to write production code in it. Go and get a decent compiler if you can't avoid using that technology.
... I'll never, for the life of me, understand comparing a high-level scripting language to almost the lowest of low-level assembly languages, as if JS doesn't give you abstractions at all.
If you can't write good code in JS, it's because you're a bad programmer.
As a veteran C++ developer, I actually quite enjoy Javascript. Once I understood that Prototypes are linked lists and that *this is a pointer that changes according to 2 simple rules, Javascript became quite easy.
I mean they even give you a GUI debugger. It's hard to get stuck for long, even though it's not not a Visual Studio.
Like you said, you have already all the abstractions you need with this language. You can do complex things and for me, if I have composition, I'm pretty much already good to go.
IDK, I've been writing JS since it was invented, so 20 years now. It was one of the first languages I learned and even then I thought it was easy. Certainly easier than C, which I was also teaching myself because it was clear at the time that nobody took JS seriously. And that was at a time when there were ZERO libraries. It took almost 10 years before anyone started serious work on libraries for JS. Up to that point, you just copy-pasta'd snippets.
I remember thinking it was easy like VB but was easier to show to other people. I still think of it in similar terms: easy to write like Python but a hell of a lot easier to deploy and show off.
It's so easy to write code and have something running. It's a whole other affair with regards to a 'structured' project involving a team of devs. If you look at the myriad of libraries and frameworks for JS, just so the dev workflow stays at a sane level without ending up with masses of balls of muds. Including a .js within a .js has to be done outside of the language ... and that is just the tip of the iceberg last time I checked.
Lol, nice. I was going to say "Learn Haskell", but I figured I'd be downvoted into oblivion. In all seriousness I am actually using that strategy and so far it seems to be working well.
Well I mentionned Dart because it is a very small step up to learn when you know Javascript. Not sure the same can be said of JS -> Haskell ... don't get me wrong I started looking into Haskell and I find it fascinating!
This is a good collection of resources that I have found are very educational and useful. That said, for me personally it was extremely important to dig into some problems concretely rather than by reading. "OK I've read about how I should do this in the ideal - now go actually set up an Angular app with a full test suite pointing at a REST API." Or perhaps - "I've got a great idea for some code art - let's try it out."
Without the follow-through I found that I could keep up in a conversation but still had doubts and issues when it came to implementation. Doing it in anger, delivering a product, as many times as possible helps a good deal in moving toward greatness.
tldr: ( my own, not the authors in the article itself )
- Read books
- Learn libraries ( author seems to like node.js and recommends libraries associated with that )
- Do exercises
- Learn how classes work in JS ( Note this is amusing to me since JS does not have classes in the typical sense [ they are implemented via libraries with prototypes and closures ] )
- Learn what Es5, Es6, ES7 are ( There are good things here, but be aware that most of these features are not implemented in most browsers and will requires shims and/or translators to even function. Be careful as they may work in your browser but not others. Test! )
- Read JS blogs and watch JS educational videos
- Practice
It's an okay article. If you are clueless how to start learning seriously this should help. Some decent books and websites are mentioned by name.
I think the "every JS developer needs to learn XYZ" is a bit off though. This is one man's perspective.
- Learn how classes work in JS ( Note this is amusing to me since JS does not have classes and everything about the way they are done is just craziness compared to a real OO language )
Are you kidding here? In ES6 classes provide nothing more additional than the closures already in use via a bit of extra utility code. Doubters should click the link here provided by Luke. It is filled with "To Be Determined" for all details of anything useful.
Do you know what classes actually do in a real OO language, or are you just a fanboy of JS?
Also, using shims or translators proves nothing. I can write in C++ and use translators to convert that to JS. What is the point here exactly?
Adding extra confusing junk onto a weak language does not make the language "better", especially when the standards you are recommending people to learn aren't even finalized.
Where is the Acid test for ES5, ES6, and ES7 features? Hell where is the Acid test for HTML5?
Oh that's right; all of this is just a pile of nonstandard junk that people are begging for and isn't really implemented.
> In ES6 classes provide nothing more additional than the closures already in use via a bit of extra utility code.
ES6 classes are sugar over prototypes, not closures. Insisting that ES6 classes aren't classes requires at the very least a basic understanding of how they are implemented.
> Do you know what classes actually do in a real OO language
JavaScript is a real OO language. Do you mean class-based?
> are you just a fanboy of JS?
Surprising vitriol here and makes you lose all credibility. Why does stating a couple of facts imply that you are a fanboy of JS?
> Also, using shims or translators proves nothing. I can write in C++ and use translators to convert that to JS. What is the point here exactly?
The point is that you stated that ES6 and ES7 code don't work cross-browser. Using Babel means that they do.
> Adding extra confusing junk onto a weak language does not make the language "better", especially when the standards you are recommending people to learn aren't even finalized.
Have you looked at the implementations of classes in jQuery, Prototype, Mootools, Dojo, etc? I have. I've used thousands of lines of codes from these libraries and fixed numerous bugs in them.
( Note I'm referring to the 'bind' function specifically in the case of jQuery as it doesn't even provide an equivalent to Class.create(). That said, John Resig himself wrote an article about this and ported out the core of Prototype [ same as I have done ] http://ejohn.org/blog/simple-javascript-inheritance/ )
Using the prototype may be the way that things get copied from the base definition to an instance, but generally closures are what allow things to have the proper scope. Arguably the scope is far more important for using something like a class than the copying. Additionally, without closures there is no way to pass of anonymous function pointers calling back into the class.
If you think you are demonstrating that I have a lack of knowledge of how this shit works, you are mistaken. But by all means, continue disregarding my points and nitpicking details instead.
You will note that here on hacker news I don't really give a shit about my credibility; I care about providing the most accurate information I can to the benefit of others.
You haven't invalidated my statement about translators at all. ES5, ES6, etc are not cross-browser compatible. Using a translator to "make it work" doesn't count. If you wish to say that C++ is cross browser compatible too then fine, but it is obscuring the root issue that those features do not exist in all the browsers, nor even the whole set of them in any one browser. This is misinformation and will mislead developers.
My last paragraph is in reference to the fact that JS/Ecmascript have never truly been "fixed". It is just a constant hodgepodge of whatever vendors decides to add on to the language.
> Have you looked at the implementations of classes in jQuery, Prototype, Mootools, Dojo, etc?
Yes, and jQuery doesn't implement classes.
> I care about providing the most accurate information I can to the benefit of others.
By calling other people fanboys after they provided a link?
> ES5, ES6, etc are not cross-browser compatible.
I guess it depends on your definition of cross-browser compatible, but ES5 is what, 5 years old now? I guess it doesn't work on IE8, but by that definition ES3 isn't cross-browser compatible because it doesn't work on IE1.
As for ES6, it's cross-browser compatible in the same way that CoffeeScript is, with the added benefit that it'll work natively in most browsers in a few years.
> My last paragraph is in reference to the fact that JS/Ecmascript have never truly been "fixed". It is just a constant hodgepodge of whatever vendors decides to add on to the language.
jQuery provides bind. That and related code is what I am referring to in that case, hence my insistence on the importance of closures. I have revised my comment to mention this as well as the fact the John Resig himself reccomends the Prototype way of doing Class.create(). By the way, Class.create() itself is implemented as a closure.
Are you claiming that CoffeeScript is cross browser compatible? If so you are just going further down the rabbit hole. To my knowledge there is not a single browser than itself is capable of parsing CoffeeScript without a helper library that doesn't come installed by default. ( Firebug comes to mind, and if I recall correctly there is a helper tool for that. I'm also aware of source mapping for debugging things such as JS in both Firebug and Chrome )
I'm using ES6 classes (and even parts of ES7) extensively in production today, and it's not nonstandard junk, and it's definitely made the language better.
> Learn how classes work in JS ( Note this is amusing to me since JS does not have classes and everything about the way they are done is just craziness compared to a real OO language )
This kind of derision is typical of people who try to force prototypal inheritance to work in the same way as classical inheritance. I suggest learning the details of the prototype chain and how it works - you'll discover it is about as powerful as classical inheritance, but in different ways.
The best thing that happened to me as a JavaScript developer was being exposed to other languages. Especially the not-so-fancy Java and C++, really opened my mind about structuring code and planning for a long-term project.
Knowing JavaScript and JavaScript frameworks is surprisingly useless for the type of work JS devs usually handle. The documentation often consists of TodoMVC type of examples and approaches. Hardly anyone explains how patterns like DDD, SOLID, advanced REST, etc. fit into this. The highly appraised Flux is in reality just a pub/sub system like many on backend (and still it's a huge step forward - it admits JS systems are large and complex).
I'm just looking at a system design graph, preparing for a new job. There are about 30 nodes representing multiple services, databases, load balancers and processes on the backend. There are two for frontend - one says "JS" and the other "JSON". This is how most people think about frontend and to be a great JavaScript developer just don't be one of them.
I agree a lot with it. I also think it's useful to work with at least one statically-typed language (like Java for example) because it teaches some good maintainability practices. In JS world, I've seen far too often creating objects in random places, as a map of parameters, passing them around, and injecting new keys to the object in other random places, and when such an object goes around too much and is augmented randomly in a myriad of ways, it's really hard to reason about it.
In Java, you'd typically create a separate class for such an object, create fields, assign types to them and document them, and have a constructor which populates the fields with sensible defaults if not provided. Sometimes it's an overkill to do it this way, but often it pays off with a better understanding of the data model. In JS you have a lot of freedom, but too much freedom leads often to a mess when enough people are working on the code.
I enjoy the freedom to use a map/object/parameter object as named parameters, speaking as somebody who has suffered through much Java ceremony.
That said, JSDoc helps a lot: make a @typedef comment for parameter objects at the top of a file, then use the type in the @param annotations of the relevant functions. Makes understanding the JS code in an IDE much easer, as well as having something worth generating HTML documentation from.
I second this. Sometime back I did Python for a production work. That for the first time gave me a true sense of Object-based inheritance v/s class based inheritance. Prior to that I used take JS way as-is. But wholeheartedly, may be not so much.
I never said it should be more complex. It, however, should be also structured somehow. There is a persistence layer, models, collections, services reasoning about them and pipelines aggregating and rendering things.
Well written JavaScript is reasonably fast and it now makes sense to optimize transported information size. Many calculations can be done front-end side then, which accidentally is also more cost-effective, since data center usage is paid, while user CPUs are more or less free (and not doing much while browsing anyway).
Books are a waste of time. Most of them are garbage to begin with, and most of them are practically obsolete by the time they are published. Few have any lasting staying power.
Besides, nobody ordained the author to be an authority on the subject. He was just a guy who wrote a book. It's zero indication of the quality of the content.
Because there is no objective way to evaluate the quality of a book before reading it, and because any useful information in most of the few good technical books is of limited lifespan, books are a waste of time. It's not just that books can be bad. It's that most books are bad, and having to wade through them is what makes them a waste of time.
Writing code without guidance is probably the slowest way you can learn something. A good book or class will save you countless hours living with the consequences of your naive mistakes. Good writers and trainers forewarn people about pitfalls by providing fair warning about common mistakes. Better writers and trainers instill good mental models that timeless help the reader solve problems.
I'll agree that there are plenty of bad books that give bad advice. The solution isn't to say books are a waste of time. The solution is to recommend better books.
If a book on software is truly obsolete anytime shortly after publication, then the tech itself isn't truly stable.
Read "The C Programming Language", by Kernighan and and Ritchie. Written decades ago, still accurate and relevant today. "The Mythical Man-Month", "The Pragmatic Programmer", "Design Patterns"... books like this will always be relevant.
Maybe a good rule is to stick to CS books that have been in continuous print for at least ten years.
If one has knowledge others can benefit from, one doesn't need to be "ordained ... an authority" to write about it.
If one cannot find a mentor to tell you this is good Javascript and this is bad Javascript, then books can fill that void.
Writing code without any guidance can only get a developer so far. He needs examples of good solid idiomatic code to progress. A good book, often by "just a guy", can provide that.
No, books are way better than reading blogs and forums. They keep a context and enforces the same style through the whole book which I find very useful
Totally agree. Best way to learn is to write, and if you want good examples to model after, check out the popular projects on Github. People are actually using those libraries and frameworks in production, unlike the toy examples in books.
One exception is more abstract thinking -- algorithms, general design principles, etc. I think a book can be handy there sometimes.
I 100% indorse "read libraries". There really is a lot of wisdom buried in them. I read through MooTools back in the day and I would go as far as to call the experience formative. Read frameworks you don't like and consider WHY they work like they do.
Missing advice: learn to program well in a few well designed programming language. JavaScript was designed in 10 days and the main reason it still exists today is incredibly strong path dependence. There's nothing wrong with wanting to become a great JavaScript developer, but one needs to become a great developer first, and JavaScript just isn't conducive to that.
I personally am so over this argument. Sure, that is roughly a fact about the time in which it was designed... but that was 20 years ago. Since then there has been a team of some of the best programmers in the world maintaining and advancing the language.
That's irrelevant; advancing the language isn't an exercise in programming language design, it's an exercise in getting everyone to support the extension and in avoiding breaking legacy code. It has almost nothing to do with the maintainer's talent as programmers or PL experts.
If you doubt this argument, consider the fact that the horrible scoping, the weak typing, the insane casting rules are still here to this day; empirically you're wrong.
Well, a lot of the little issues are being slowly fixed (see let and scoping in ES6). This goes back to the point of the person you are responding to.
This is a thought more than a full-fledged argument, but perhaps little issues with the language actually can and do make people better developers when they are aware of them. My friend started driving a scooter. Dallas isn't particularly conducive to that. My friend says he has since become a better driver because he knows one little screw up by him or someone else can end his life. Similarly, you'd better be aware of weak typing and casting and code accordingly or you might get hurt. Of course, you shouldn't have to...but that doesn't make people worse developers.
But the truth is, JS has a lot of features which make it great for becoming a good developer. It's less class-based than Ruby and has better lambdas than Python which I would argue make it better for functional programming than either.
Yes, "let" will finally fix the horrible scoping - 20 years after the creation of JavaScript. In the meantime you'll still be stuck using lovely constructs like === and !==
And yes, JS support for lambda expression is surprisingly nice, but that is basically the only nice surprise.
Since then there has been a team of some of the best programmers in the world maintaining and advancing the language.
JavaScript engines have seen a lot of effort from some of the best compiler and JIT experts in the industry, including former Self VM architects, yes.
The language itself? I honestly can't say that. Lua is a way better ECMAScript than ECMAScript itself, and the focus should have been on trimming it down to a smaller but easily extensible core, as opposed to the feature piling that's going on.
"Since then there has been a team of some of the best programmers in the world maintaining and advancing the language."
If you build a church from chewing gum and then get Gustaf Eiffel to design a few towers to it from steel with furbishments by Antonio Gaudi the fact still remains there is a heap of melting gum at the bottom.
Stuff that needs to be designed up front cannot be fixed after the fact regardless of the amount of ducktape and personell applied.
Thanks for this link. I will be reading it for sure. I also stumbled on the annotated source of Underscore.js a few days ago (http://underscorejs.org/docs/underscore.html). Would love any more stuff like this that anyone knows of.
Why oh why are those not comments within the source file? It would help me so much to have comments like those in software...
Generally I think that a linear step-by-step description is often not the best way though, often you would have to explain concepts or the bigger picture first.
What prompted me to develop as a JavaScript developer was being put in charge of a major project that was mostly JS code. Up till then, I had done some JS work, using jQuery to add animations and interactions to a UI and some ajax. Doing this JS project exposed me to pretty much everything you can do with JS, and I learned it all pretty quickly so I could start contributing to the project.
I only got this project too because the dev previously in charge of the project left the company and I asked about it. It's another lesson to new developers: never let an opportunity pass you by.
If you're already a decent enough developer and just need to get your grips on JavaScript, I'd say that most books listed aren't that useful. A decent enough online reference will get you going and after that you'll have to consider that JS is a pretty large dung heap by now where you probably won't get a lot of mileage out of inhaling dust from the crusty parts. Unless you're an enterprise developer tasked with maintaining your company's Dojo application.
If you're a new developer coming into JS from a more tabula rasa situation (possibly these days), I'd still say that most of those books are wasted, and you'd probably get a better mileage out ouf SICP or the GoF book than most Ninja/21days/Dummies tomes.
The core of JS is small enough, and the rest is highly dependent on your task, scope and framework. No jQuery book will help you with your intranet extjs app or your state of the art fluxified React SPA. You'll have to wade through code to get there, preferably as much of your own as possible.
And the most important thing: Pick something and stick with it. No mid-project framework/build tool/library changes. Even "obsolete" tech still works better than falling into the Duke Nukem hole. So don't get nervous about still using "grunt" when all the cool kids are using "gapoodle".
For the decent developers picking up Javascript, http://learnxinyminutes.com/docs/javascript/ is hard to beat. All the basic syntax and language features in one page without trying to explain to you what a while loop does.
// Statements can be terminated by ;
doStuff();
// ... but they don't have to be, as semicolons are automatically inserted
// wherever there's a newline, except in certain cases.
doStuff()
// Because those cases can cause unexpected results, we'll keep on using
// semicolons in this guide.
I haven't gotten much into Javascript yet, but is there any reason I would not terminate with semicolons? Without understanding which "certain cases" won't have them inserted automatically, relying on that feels like asking for trouble.
My understanding is that the original decision was to make life easier for the programmer: if you forget, we'll put one in there for you. Myself, I'd rather be told that I made a mistake, then have it ignored, because how does the compiler know what I really wanted?
Instead of being told there's some problem with the code, it inserts a semi-colon into an arguably ludicrous location, and then gives you a differen error.
Would probably make compiler writers' jobs easier if they just spit out errors.
The actual reason that third function compiles, and the fourth does not, is that
{
x: 0
}
is a block statement with a label x. Try it in your console, it returns 0. The last one is an object literal outside an expression, which is a syntax error.
In addition to that, the return statement is 'restricted production' where the line break itself is a terminator, this has nothing to do with semi-colons or ASI.
As a general case I recommend always terminating each statement with a semi-colon. Then it is explicit to the interpreter and other coders (and "other coders" includes "you six months later when you've forgotten most of what you did today") that you intended this to be the end of the statement and the next line to be the start of a new one.
Only ever leave the semi-colon out at the end of a line when you are explicitly using a multi-line statement to make your code more readable.
This makes your intent unambiguous in both cases; to the interpreter/compiler, to other tools, and to other humans.
Coming from a mostly C, Java and Perl background, I've got no personal issues with semi-colons, and often find myself adding them in languages where they're completely unnecessary, especially when switching back and forth.
Having said that, your argument could also apply to operator precedence and parentheses. Yet most languages implement this, and most users don't add them unless they're in doubt (more often with e.g. logical operators than arithmetic ones).
The rules aren't that complicated and the corner cases are (IMHO) a bit overrated. The way I see it, the more pressing reason would be the accepted JavaScript style, just like the positioning of braces.
Ah, the "minify" bug: forcing people to put statement separators into a line oriented language.
Think of semicolons in JS like colons in BASIC: they let you stack multiple statements on a line. Then, go learn what the language REALLY thinks is the end of a statement, which is not "I put in a semicolon".
Too bad JS doesn't use (an explicit) backslash for line continuation, rather than guessing when a line/statement was done :-(
Missing semicolons have more pitfalls than just minifiers being naughty.
return
someExpression
will parse out as:
return;
someExpression;
and you have assumption of function call in
x = y
(z).whatever()
which parses out as
x = y(z).whatever()
Nothing hint or lint wouldn't catch though. IMHO, you really need to be special to avoid explicitly writing out semicolons, but to each his own. I can maybe give it a point for unique style. :)
Wow, I got schooled. Did not realize rule 4 about lines starting with array subscript brackets or function argument parens. (regardless of the line's intent of perhaps being an array literal or simply starting with an expression to be evaluated early)
The sad reality, taking the second link to its satirical conclusion, is that all JS should be written on one line, with semicolons between statements. No guessing about the effects of line breaks if there aren't any. "I say we take off and nuke the entire site from orbit - it's the only way to be sure." :-)
How would semicolons have prevented the first of those misunderstandings?
-- Don't get me wrong, those are good cases to know what is going to happen. But I think you are making the case that semicolons provide a false security blanket, since the language can complete a line you meant to wrap, or, alas, merge 2 lines you meant to have separate.
I think shell (and a few other languages) actually got it right: 1 line = 1 statement, unless there is an explicit continuation.
I disagree with the last point. If you can make sure that the change is worth it, that you understand the new technology very well, and if you make a commitment to follow through and do all the necessary work, you wont fall into the "Duke Nukem" hole.
(The problem of course is that often times we don't take the time to make the necessary evaluation and want to make a change just for the sake of learning the new shiny)
I'm talking about the beginning JS programmer. So it's quite likely that they don't understand the technology they're currently working on and thus have bigger problems evaluting the new one, as there's no good point of comparison.
Also, I hope that the first project a JS newbie does isn't a 100'000 line app, but something more bite-sized, and thus you really don't have to wait months to get to use the new stack or tool. Quite often this kind of decision making happens when the project is 80% done and you have to face a few things that aren't that easy or your code has become a bit too complicated. And yes, the new tool could solve that and you might even end up re-implementing bits and pieces of that. This might not be the most effective use of your time, but it's a good learning experience.
You might be right in that it technically is the best approach, but pedagogically the value of starting with a more specific jQuery, or Rails book is that it's just more fun to build something that immediately does something that you can see and play around with, especially if you can do so right within the browser.
Of course, it's not a good thing to stop there, but in my experience it often acts as a gateway for beginners to start actually learning 'proper' programming.
My brother, for example, has been working through the Rails tutorial, and already he's starting to read more general ruby books, doing javascript tutorials, and thinking about building a game for the browser using Rails as a backend. Plus, he'll be able to make money much sooner this way, which is a great incentive for him to keep at it.
I think it totally depends on the problem domain you are working with. There are so many different ways to use javascript it is overwhelming. There are also lots of ways to structure it. I feel like a very good understanding of a widely used OOP language such as Java is a good place to start before jumping into the wild west of javascript programming.
Tastes in books varies wildly between developers: there are many on there that I wouldn't say helped me as much as others, but to each their own!
With that in mind, I'd put a plug in for David Herman's _Effective JavaScript_. It goes beyond simply stating the mechanics of JavaScript into what pitfalls can be had, and uncommon but critical factors to consider when writing your code. The point about UTF-16 code points in strings alone makes it a valuable resource.
Just adding my two cents. Wanna be a good JS dev? Go play around with a lisp. Like Clojure for a month or two. Get comfortable with functional programming. Then come back to JS. So many people come from a OOP to JS and they have a bad time with it. JS is more like a lisp with C syntax than it is a traditional OO language. Learning Clojure, not only improved my JS abilities, but just my over all programming maturity. IMO. Additionally, I agree with the author about reading books, and libraries. It's always good advice for any language.
Interesting, thanks for this perspective. As someone who started with C/C++ (and a hint of Python) but has recently started working in Clojure, I'm now very encouraged to re-try JS.
Indeed. Personally I'm used to think in functional ways: map, fold, function composition, immutability... I'd like to be good at Haskell but I'm always having lots of pain dealing with it, because I never see the end of the learning curve.
I've found JS to be a nice middle land where I can get productive functionally without too much hassle. It's like a good friend who understands my way of thinking without being in the way too much. Underscore.js hits the sweet spot for me: _.chain(...).map(...).filter(...).value() is verbose but surprinsingly readable. I'm not a fan of Python map() syntactically, and I absolutely hate C++11's std::transform.
If you want to make that even less verbose, try myArray.map(...).filter(...) (those methods don't have to come from underscore, they exist on the Array prototype as of ES5).
If you've only been exposed to OOP, and you don't have the bandwidth for learning an unrelated language, then start using a functional library like Underscore. Just use it everywhere, even if you think it's ridiculous. Don't use for-loops, use _.each. Try to think of every problem in terms of chaining map, reduce, zip, pluck, groupBy, etc. Do whatever you can to avoid side-effects.
Once you're comfortable with it, try reading "Functional JavaScript".
You'll quickly develop a taste for when OOP or functional is appropriate, but I think the best way to get to that point is to immerse yourself in functional programming first, which might mean writing some ridiculous functional stuff, but the long-term payoff will be worth it.
JS brings a lot more to the table than just a scripted version of "C++ for retards" (aka Java), as it also lets you make use of many FP concepts like higher order functions and functional (vs object) composition.
For example, using currying (aka "dependency injection for functions") lets you often do with a single function what would take a silly-long class to do in Java. Use currying to inject leading parameters to a function that would normally be in the constructor (or setters, ugh) in a Java class, then the remaining "short arg list" function acts like the oh-too-common one actual "we're ready, now do something" method in a class.
Indeed, so the tale goes: Brendan Eich was originally going to make Scheme for the browser, but Netscape said their browser language had to look like Java, and that's how we wound up with this odd vaguely-functional browser language called Javascript.
In light of that, definitely seconded. Using Clojure (and watching Rich Hickey's amazing talks) made me a much better developer, and especially a better JS developer.
Somewhat relatedly, one thing I personally like about CoffeeScript is that it really lets the functional, Lisp-y side of Javascript shine through by melting away all the crufty syntax. That really helped me apply some of the style I picked up from Clojure.
Downside is that after using a proper functional language (clojure[script]) you end up wanting some really basic things such as immutable core data structures.
I feel like if you start from scratch on a javascript project, it's possible to program in a functional manner. I've found it really tough to introduce functional concepts to an already full stack javascript codebase.
BTW: I'd recommend ramda [1] for those interested in functional javascript programming. The auto-currying makes it way more powerful than underscore/lodash in terms of encouraging pure reusable functions.
To be good at something, you do not need to know things outside of the area. It might however be helpful if you need to go "outside the box". But to be an expert at the things in the box, you only have to know about the box ...
That said, before I started with Node.JS and understood it's "patterns" JavaScript was just some evil necessary to get things to work. But after learning the module patterns of Node.JS, JavaScript started to get fun!! And the more ppl that understands "modules", the more fun it gets! So go learn about modules and even try making your own!
I guess Node.JS is now part of the JavaScript box.
"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects."
— Robert Heinlein, Time Enough for Love
I have a hard time thinking of "web programmer" as "polymath" and worrying that it's not specialized enough.
Maybe it's person-dependent, but I've learn most JS from MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript) _and_ collaborating with others (plus a lot of blog posts, code snippents, and in general: reading code by good developers (side note: it's why I hate minification - I habitually read code on webpages)).
For books the main problem is that they are getting obsolete quickly (JS is a rapidly-changing technology) and, except for very basics, somewhat opinionated and task-dependent.
Force yourself to lint your code. Having clean code is like having good handwriting, it makes content of your projects easier to understand and drastically improves how you think about what you're building.
By all means - it's not actually mine though. It's a derivative of "God can draw a straight line with a crooked stick." It's generally attributed to Martin Luther, though I didn't really know until I looked it up just now :)
This is sort of like asking should you learn Swift or Objective-C, albeit much less difference between syntaxes. You can certainly get the job done on ES6, and the future is certainly in that direction, but all browsers still run ES5, so if you want to get paid for your work, you'd need to still know that syntax.
Babel is a great tool to let you use some of ES6's features now, but it will still help in debugging to know ES5 syntax since Babel transforms it at runtime.
If you been doing a lot of JS for web stuff, and used SO etc to check things but don't have a thorough understanding of the language I would recommend the book "JavaScript the good parts"
JavaScript the Good Parts shouldn't be the recommended book anymore (and I think even Crockford himself said something along that line in one of his newer videos, couldn't find it though... it's been a while)
I definitely do not consider myself great JavaScript developer. Not even mediocre. Code by some people that now do JavaScript lectures, I've refactored and made at least order of magnitude faster, so there's that.
There's one important thing I've already learned though and I'll do you a solid - be a total nazi to your code.[1]
At the start, it's easy to get impression that it's all loosey-goosey-everything-works kinda thing, and it actually is...at small scale! When you get to medium-sized thing, all hell starts to break loose, and I'm not talking just callback hell. You can avoid all that with modest amount of discipline.
I'm aware many people have qualms with JSLint, some even with JSHint. But it doesn't matter what you use as long as you keep consistency. Those two tools help you with that. If you can be disciplined without it, sure, go for it. Just reading on possible configuration options for JSHint already made me consider many potential pitfalls I wouldn't have even thought of otherwise..
As far as learning goes, I'm definitely recommending learning as-you-go. To hell with academics - this is JavaScript, language made in few weeks[2]. You can develop amazingly accurate feel for the language in spite of not knowing rigorous abstracts. You're not sure what new actually does, and you're on deadline? Make a note - "figure out new" - and move along. When you manage to scrounge few hours of your busy week, run through those questions of yours across plethora of amazing resources online, head over to #Node.js or ##javascript on freenode, ask and ye shall receive.
In JavaScript, there's about a million ways one can make something work, an immense solution space. Are you sure your attack vector is good enough? Refactor aggresively!
[1] I wanted to go with "anal" instead of "nazi". But you get the idea.
170 comments
[ 13.9 ms ] story [ 363 ms ] threadI would argue that JS should be handled analogously to Assembler: Good for you if you understand it, but only highly trained field specialists in protective suits dare to write production code in it. Go and get a decent compiler if you can't avoid using that technology.
If you can't write good code in JS, it's because you're a bad programmer.
But academically being able to write in a certain language is still not the same thing as productivity combined with certain quality guarantees.
I remember thinking it was easy like VB but was easier to show to other people. I still think of it in similar terms: easy to write like Python but a hell of a lot easier to deploy and show off.
I'm sorry, but that's just an absurd statement. JS isn't that bad or confusing.
https://brendaneich.com/2015/06/from-asm-js-to-webassembly/
Do you write that manually, too?
0: http://www.purescript.org/
1: https://leanpub.com/purescript/read
Without the follow-through I found that I could keep up in a conversation but still had doubts and issues when it came to implementation. Doing it in anger, delivering a product, as many times as possible helps a good deal in moving toward greatness.
- Read books
- Learn libraries ( author seems to like node.js and recommends libraries associated with that )
- Do exercises
- Learn how classes work in JS ( Note this is amusing to me since JS does not have classes in the typical sense [ they are implemented via libraries with prototypes and closures ] )
- Learn what Es5, Es6, ES7 are ( There are good things here, but be aware that most of these features are not implemented in most browsers and will requires shims and/or translators to even function. Be careful as they may work in your browser but not others. Test! )
- Read JS blogs and watch JS educational videos
- Practice
It's an okay article. If you are clueless how to start learning seriously this should help. Some decent books and websites are mentioned by name.
I think the "every JS developer needs to learn XYZ" is a bit off though. This is one man's perspective.
ES6 brings classes: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- Learn what Es5, Es6, ES7 are ( good for confusing yourself and writing code that won't work cross-browser... )
Babel means you can write ES6 and ES7 code and make it cross browser: https://babeljs.io/
Do you know what classes actually do in a real OO language, or are you just a fanboy of JS?
Also, using shims or translators proves nothing. I can write in C++ and use translators to convert that to JS. What is the point here exactly?
Adding extra confusing junk onto a weak language does not make the language "better", especially when the standards you are recommending people to learn aren't even finalized.
Where is the Acid test for ES5, ES6, and ES7 features? Hell where is the Acid test for HTML5?
Oh that's right; all of this is just a pile of nonstandard junk that people are begging for and isn't really implemented.
ES6 classes are sugar over prototypes, not closures. Insisting that ES6 classes aren't classes requires at the very least a basic understanding of how they are implemented.
> Do you know what classes actually do in a real OO language
JavaScript is a real OO language. Do you mean class-based?
> are you just a fanboy of JS?
Surprising vitriol here and makes you lose all credibility. Why does stating a couple of facts imply that you are a fanboy of JS?
> Also, using shims or translators proves nothing. I can write in C++ and use translators to convert that to JS. What is the point here exactly?
The point is that you stated that ES6 and ES7 code don't work cross-browser. Using Babel means that they do.
> Adding extra confusing junk onto a weak language does not make the language "better", especially when the standards you are recommending people to learn aren't even finalized.
Where exactly did he make this argument?
http://paulgraham.com/reesoo.html
Using the prototype may be the way that things get copied from the base definition to an instance, but generally closures are what allow things to have the proper scope. Arguably the scope is far more important for using something like a class than the copying. Additionally, without closures there is no way to pass of anonymous function pointers calling back into the class.
If you think you are demonstrating that I have a lack of knowledge of how this shit works, you are mistaken. But by all means, continue disregarding my points and nitpicking details instead.
You will note that here on hacker news I don't really give a shit about my credibility; I care about providing the most accurate information I can to the benefit of others.
You haven't invalidated my statement about translators at all. ES5, ES6, etc are not cross-browser compatible. Using a translator to "make it work" doesn't count. If you wish to say that C++ is cross browser compatible too then fine, but it is obscuring the root issue that those features do not exist in all the browsers, nor even the whole set of them in any one browser. This is misinformation and will mislead developers.
My last paragraph is in reference to the fact that JS/Ecmascript have never truly been "fixed". It is just a constant hodgepodge of whatever vendors decides to add on to the language.
Yes, and jQuery doesn't implement classes.
> I care about providing the most accurate information I can to the benefit of others.
By calling other people fanboys after they provided a link?
> ES5, ES6, etc are not cross-browser compatible.
I guess it depends on your definition of cross-browser compatible, but ES5 is what, 5 years old now? I guess it doesn't work on IE8, but by that definition ES3 isn't cross-browser compatible because it doesn't work on IE1.
As for ES6, it's cross-browser compatible in the same way that CoffeeScript is, with the added benefit that it'll work natively in most browsers in a few years.
> My last paragraph is in reference to the fact that JS/Ecmascript have never truly been "fixed". It is just a constant hodgepodge of whatever vendors decides to add on to the language.
That's really not the case anymore.
Are you claiming that CoffeeScript is cross browser compatible? If so you are just going further down the rabbit hole. To my knowledge there is not a single browser than itself is capable of parsing CoffeeScript without a helper library that doesn't come installed by default. ( Firebug comes to mind, and if I recall correctly there is a helper tool for that. I'm also aware of source mapping for debugging things such as JS in both Firebug and Chrome )
This kind of derision is typical of people who try to force prototypal inheritance to work in the same way as classical inheritance. I suggest learning the details of the prototype chain and how it works - you'll discover it is about as powerful as classical inheritance, but in different ways.
Knowing JavaScript and JavaScript frameworks is surprisingly useless for the type of work JS devs usually handle. The documentation often consists of TodoMVC type of examples and approaches. Hardly anyone explains how patterns like DDD, SOLID, advanced REST, etc. fit into this. The highly appraised Flux is in reality just a pub/sub system like many on backend (and still it's a huge step forward - it admits JS systems are large and complex).
I'm just looking at a system design graph, preparing for a new job. There are about 30 nodes representing multiple services, databases, load balancers and processes on the backend. There are two for frontend - one says "JS" and the other "JSON". This is how most people think about frontend and to be a great JavaScript developer just don't be one of them.
In Java, you'd typically create a separate class for such an object, create fields, assign types to them and document them, and have a constructor which populates the fields with sensible defaults if not provided. Sometimes it's an overkill to do it this way, but often it pays off with a better understanding of the data model. In JS you have a lot of freedom, but too much freedom leads often to a mess when enough people are working on the code.
That said, JSDoc helps a lot: make a @typedef comment for parameter objects at the top of a file, then use the type in the @param annotations of the relevant functions. Makes understanding the JS code in an IDE much easer, as well as having something worth generating HTML documentation from.
It just doesn't make any sense.
Well written JavaScript is reasonably fast and it now makes sense to optimize transported information size. Many calculations can be done front-end side then, which accidentally is also more cost-effective, since data center usage is paid, while user CPUs are more or less free (and not doing much while browsing anyway).
Besides, nobody ordained the author to be an authority on the subject. He was just a guy who wrote a book. It's zero indication of the quality of the content.
Just write code. Practice, practice, practice.
Because there is no objective way to evaluate the quality of a book before reading it, and because any useful information in most of the few good technical books is of limited lifespan, books are a waste of time. It's not just that books can be bad. It's that most books are bad, and having to wade through them is what makes them a waste of time.
Here are a few books that I see at the top of the lists almost every time this topic comes up:
The Mythical Man-Month
The Pragmatic Programmer: From Journeyman to Master
Code Complete
Writing code without guidance is probably the slowest way you can learn something. A good book or class will save you countless hours living with the consequences of your naive mistakes. Good writers and trainers forewarn people about pitfalls by providing fair warning about common mistakes. Better writers and trainers instill good mental models that timeless help the reader solve problems.
I'll agree that there are plenty of bad books that give bad advice. The solution isn't to say books are a waste of time. The solution is to recommend better books.
Read "The C Programming Language", by Kernighan and and Ritchie. Written decades ago, still accurate and relevant today. "The Mythical Man-Month", "The Pragmatic Programmer", "Design Patterns"... books like this will always be relevant.
Maybe a good rule is to stick to CS books that have been in continuous print for at least ten years.
If one cannot find a mentor to tell you this is good Javascript and this is bad Javascript, then books can fill that void.
Writing code without any guidance can only get a developer so far. He needs examples of good solid idiomatic code to progress. A good book, often by "just a guy", can provide that.
One exception is more abstract thinking -- algorithms, general design principles, etc. I think a book can be handy there sometimes.
If you doubt this argument, consider the fact that the horrible scoping, the weak typing, the insane casting rules are still here to this day; empirically you're wrong.
This is a thought more than a full-fledged argument, but perhaps little issues with the language actually can and do make people better developers when they are aware of them. My friend started driving a scooter. Dallas isn't particularly conducive to that. My friend says he has since become a better driver because he knows one little screw up by him or someone else can end his life. Similarly, you'd better be aware of weak typing and casting and code accordingly or you might get hurt. Of course, you shouldn't have to...but that doesn't make people worse developers.
But the truth is, JS has a lot of features which make it great for becoming a good developer. It's less class-based than Ruby and has better lambdas than Python which I would argue make it better for functional programming than either.
And yes, JS support for lambda expression is surprisingly nice, but that is basically the only nice surprise.
JavaScript engines have seen a lot of effort from some of the best compiler and JIT experts in the industry, including former Self VM architects, yes.
The language itself? I honestly can't say that. Lua is a way better ECMAScript than ECMAScript itself, and the focus should have been on trimming it down to a smaller but easily extensible core, as opposed to the feature piling that's going on.
If you build a church from chewing gum and then get Gustaf Eiffel to design a few towers to it from steel with furbishments by Antonio Gaudi the fact still remains there is a heap of melting gum at the bottom.
Stuff that needs to be designed up front cannot be fixed after the fact regardless of the amount of ducktape and personell applied.
Also, it seems like a big jump to go from doing exercises to giving lectures.
Is there a 'Genius' (nee 'Rap.Genius') type resource that annotates well known open source code?
Generally I think that a linear step-by-step description is often not the best way though, often you would have to explain concepts or the bigger picture first.
http://underscorejs.org/underscore.js
Docco Source: http://jashkenas.github.io/docco/
Backbone Source: http://backbonejs.org/docs/backbone.html
CoffeeScript Source: http://coffeescript.org/documentation/docs/grammar.html
https://watchandcode.com/courses/eloquent-javascript-the-ann...
I only got this project too because the dev previously in charge of the project left the company and I asked about it. It's another lesson to new developers: never let an opportunity pass you by.
If you're a new developer coming into JS from a more tabula rasa situation (possibly these days), I'd still say that most of those books are wasted, and you'd probably get a better mileage out ouf SICP or the GoF book than most Ninja/21days/Dummies tomes.
The core of JS is small enough, and the rest is highly dependent on your task, scope and framework. No jQuery book will help you with your intranet extjs app or your state of the art fluxified React SPA. You'll have to wade through code to get there, preferably as much of your own as possible.
And the most important thing: Pick something and stick with it. No mid-project framework/build tool/library changes. Even "obsolete" tech still works better than falling into the Duke Nukem hole. So don't get nervous about still using "grunt" when all the cool kids are using "gapoodle".
Here's a good one: http://stackoverflow.com/questions/18986144/javascript-compi...
Instead of being told there's some problem with the code, it inserts a semi-colon into an arguably ludicrous location, and then gives you a differen error.
Would probably make compiler writers' jobs easier if they just spit out errors.
In addition to that, the return statement is 'restricted production' where the line break itself is a terminator, this has nothing to do with semi-colons or ASI.
If this is your preference, JSLint has you covered. Really, every JS developer should be using a linter and tweak it to fit their coding preferences.
Only ever leave the semi-colon out at the end of a line when you are explicitly using a multi-line statement to make your code more readable.
This makes your intent unambiguous in both cases; to the interpreter/compiler, to other tools, and to other humans.
Having said that, your argument could also apply to operator precedence and parentheses. Yet most languages implement this, and most users don't add them unless they're in doubt (more often with e.g. logical operators than arithmetic ones).
The rules aren't that complicated and the corner cases are (IMHO) a bit overrated. The way I see it, the more pressing reason would be the accepted JavaScript style, just like the positioning of braces.
Think of semicolons in JS like colons in BASIC: they let you stack multiple statements on a line. Then, go learn what the language REALLY thinks is the end of a statement, which is not "I put in a semicolon".
Too bad JS doesn't use (an explicit) backslash for line continuation, rather than guessing when a line/statement was done :-(
Regardless:
http://blog.izs.me/post/2353458699/an-open-letter-to-javascr...
Although to be fair:
http://benalman.com/news/2013/01/advice-javascript-semicolon...
The sad reality, taking the second link to its satirical conclusion, is that all JS should be written on one line, with semicolons between statements. No guessing about the effects of line breaks if there aren't any. "I say we take off and nuke the entire site from orbit - it's the only way to be sure." :-)
-- Don't get me wrong, those are good cases to know what is going to happen. But I think you are making the case that semicolons provide a false security blanket, since the language can complete a line you meant to wrap, or, alas, merge 2 lines you meant to have separate.
I think shell (and a few other languages) actually got it right: 1 line = 1 statement, unless there is an explicit continuation.
(The problem of course is that often times we don't take the time to make the necessary evaluation and want to make a change just for the sake of learning the new shiny)
Also, I hope that the first project a JS newbie does isn't a 100'000 line app, but something more bite-sized, and thus you really don't have to wait months to get to use the new stack or tool. Quite often this kind of decision making happens when the project is 80% done and you have to face a few things that aren't that easy or your code has become a bit too complicated. And yes, the new tool could solve that and you might even end up re-implementing bits and pieces of that. This might not be the most effective use of your time, but it's a good learning experience.
Of course, it's not a good thing to stop there, but in my experience it often acts as a gateway for beginners to start actually learning 'proper' programming.
My brother, for example, has been working through the Rails tutorial, and already he's starting to read more general ruby books, doing javascript tutorials, and thinking about building a game for the browser using Rails as a backend. Plus, he'll be able to make money much sooner this way, which is a great incentive for him to keep at it.
With that in mind, I'd put a plug in for David Herman's _Effective JavaScript_. It goes beyond simply stating the mechanics of JavaScript into what pitfalls can be had, and uncommon but critical factors to consider when writing your code. The point about UTF-16 code points in strings alone makes it a valuable resource.
I've found JS to be a nice middle land where I can get productive functionally without too much hassle. It's like a good friend who understands my way of thinking without being in the way too much. Underscore.js hits the sweet spot for me: _.chain(...).map(...).filter(...).value() is verbose but surprinsingly readable. I'm not a fan of Python map() syntactically, and I absolutely hate C++11's std::transform.
If you've only been exposed to OOP, and you don't have the bandwidth for learning an unrelated language, then start using a functional library like Underscore. Just use it everywhere, even if you think it's ridiculous. Don't use for-loops, use _.each. Try to think of every problem in terms of chaining map, reduce, zip, pluck, groupBy, etc. Do whatever you can to avoid side-effects.
Once you're comfortable with it, try reading "Functional JavaScript".
You'll quickly develop a taste for when OOP or functional is appropriate, but I think the best way to get to that point is to immerse yourself in functional programming first, which might mean writing some ridiculous functional stuff, but the long-term payoff will be worth it.
JSON starts to look like funny s-expressions.
JS brings a lot more to the table than just a scripted version of "C++ for retards" (aka Java), as it also lets you make use of many FP concepts like higher order functions and functional (vs object) composition.
For example, using currying (aka "dependency injection for functions") lets you often do with a single function what would take a silly-long class to do in Java. Use currying to inject leading parameters to a function that would normally be in the constructor (or setters, ugh) in a Java class, then the remaining "short arg list" function acts like the oh-too-common one actual "we're ready, now do something" method in a class.
Indeed, so the tale goes: Brendan Eich was originally going to make Scheme for the browser, but Netscape said their browser language had to look like Java, and that's how we wound up with this odd vaguely-functional browser language called Javascript.
In light of that, definitely seconded. Using Clojure (and watching Rich Hickey's amazing talks) made me a much better developer, and especially a better JS developer.
Somewhat relatedly, one thing I personally like about CoffeeScript is that it really lets the functional, Lisp-y side of Javascript shine through by melting away all the crufty syntax. That really helped me apply some of the style I picked up from Clojure.
I cringe when I see Java/C++ style code in JavaScript. Unfortunately it's how most JS coders write code.
Downside is that after using a proper functional language (clojure[script]) you end up wanting some really basic things such as immutable core data structures.
I feel like if you start from scratch on a javascript project, it's possible to program in a functional manner. I've found it really tough to introduce functional concepts to an already full stack javascript codebase.
BTW: I'd recommend ramda [1] for those interested in functional javascript programming. The auto-currying makes it way more powerful than underscore/lodash in terms of encouraging pure reusable functions.
[1]: https://github.com/ramda/ramda
That said, before I started with Node.JS and understood it's "patterns" JavaScript was just some evil necessary to get things to work. But after learning the module patterns of Node.JS, JavaScript started to get fun!! And the more ppl that understands "modules", the more fun it gets! So go learn about modules and even try making your own!
I guess Node.JS is now part of the JavaScript box.
I have a hard time thinking of "web programmer" as "polymath" and worrying that it's not specialized enough.
For books the main problem is that they are getting obsolete quickly (JS is a rapidly-changing technology) and, except for very basics, somewhat opinionated and task-dependent.
Am I over-simplifying?
Thanks.
Should I jump into ES6 directly or learn ES5 and learn ES6 when it is implemented across all browsers ?
Babel is a great tool to let you use some of ES6's features now, but it will still help in debugging to know ES5 syntax since Babel transforms it at runtime.
There's one important thing I've already learned though and I'll do you a solid - be a total nazi to your code.[1]
At the start, it's easy to get impression that it's all loosey-goosey-everything-works kinda thing, and it actually is...at small scale! When you get to medium-sized thing, all hell starts to break loose, and I'm not talking just callback hell. You can avoid all that with modest amount of discipline.
I'm aware many people have qualms with JSLint, some even with JSHint. But it doesn't matter what you use as long as you keep consistency. Those two tools help you with that. If you can be disciplined without it, sure, go for it. Just reading on possible configuration options for JSHint already made me consider many potential pitfalls I wouldn't have even thought of otherwise..
As far as learning goes, I'm definitely recommending learning as-you-go. To hell with academics - this is JavaScript, language made in few weeks[2]. You can develop amazingly accurate feel for the language in spite of not knowing rigorous abstracts. You're not sure what new actually does, and you're on deadline? Make a note - "figure out new" - and move along. When you manage to scrounge few hours of your busy week, run through those questions of yours across plethora of amazing resources online, head over to #Node.js or ##javascript on freenode, ask and ye shall receive.
In JavaScript, there's about a million ways one can make something work, an immense solution space. Are you sure your attack vector is good enough? Refactor aggresively!
[1] I wanted to go with "anal" instead of "nazi". But you get the idea.
[2] ...by some amazing dude though.