This is a very solid foundation to work with, for anyone who might have struggled with the contexts and how arrow functions, local variables, thises (hah) and prototypes fit into the bigger picture.
It also clearly shows that Javascript is not the mess that it looks like from a beginner's perspective. Yes, anyone can create a 15-20 min video about how == and === can mess up stuff, how you cant just pass around a function with a this in it without being careful, how NaN is wtf, and all that jazz. But at the end of the day, stick to this language long enough and it works for you.
I wonder why nobody has created a version of JavaScript that just throws exceptions for all the WTF cases? That is, it would basically be a mode like 'use strict-at-runtime'; .
This would be incompatible, but it would be a useful development aid. Surely most frameworks like React and Angular avoid these corners of the language, and they could be trivially modified to run on such an interpreter? It would improve their code quality.
I know this would be a large amount of work, but it doesn't seem that huge compared to all the other JavaScript infrastructure out there (parsers, transpilers, etc.). There are more independent JavaScript interpreters written than interpreters of any other language, AFAICT. At least before ES6, writing a JS interpreter was a one-talented-person project, not a huge team project like a JIT.
I guess one reason is that the DOM and node.js bindings aren't easy to reproduce. But I would think people still run their unit tests in a limited environment and it would be useful for some code. It could even be based on narcissus -- JavaScript in JavaScript?
Probably because the WTF cases are exaggerated. After a couple of months coding JS you will know it well enough so it doesn't bite you. It really is a non-issue for people who work with it daily.
I agree it might not be an issue for professional programmers, given the right tools.
But there are plenty of people who would recommend Python over JS as a first programming language for exactly this reason. Python gives better error messages and has fewer WTFs.
I think JS could be a good teaching language if it were not for the confusion over types, which is an important thing for a beginning programmer to understand.
I think the most common way to accomplish that idea is to run a linter. Linters should be able to statically catch most of the unsafe operations you're probably describing.
Yeah, that's probably true -- linters do an OK job at attacking this problem.
But then there are still people complaining about JS semantics... I think there is a gulf between what tools professional JS programmers use, and what tools X programmers use when they write JavaScript, where X != JavaScript.
I think most JS fans these days recognize the inherent problems with JS, and work around them with best practices (on the lenient side) or linters and more advanced preprocessors like type checkers (on the strict side). At the end of the day, by far the main advantage of JS is the fact that there are mature and reliably-updated implementations with a relatively easy and open distribution platform on virtually every modern computing device (browsers and the World Wide Web). Some of the other fundamentals of the language are nice (particularly first-class functions), while the bad fundamentals (particularly the hopelessly messy type coercion) are now well-recognized and hopefully avoided through various techniques.
> why nobody has created a version of JavaScript that just throws exceptions for all the WTF cases?
Google experimented with something they called "strong mode". Classes were read-only, accessing nonexistent properties was an error, and things like that.
I liked it. Unfortunately, the experiment didn't go anywhere and strong mode was removed from Chrome.
Dart is somewhat similar, though. It got more straightforward semantics than JS and most of those WTF things are an error.
Sure this car get dust on the ventilation, and you can mess up if you use the 3rd gear and you can't really use the blinkers without being careful and the seat warmers are wtf.
But in the end of the day, stick to this car long enough and it works for you.
Plus the most popular road of the world only accept this car so take it or leave.
I fail to get the flak that javascript faces ! Coming from java it was a breath of fresh air. This was the car that let me drive without a seatbelt when i wanted, let the doors be open if i wanted, stepping on the gas accelerated without fail and the brakes functioned fine, i could change the gearbox orientation, choose which side the steering wheel i wanted to be in general let me do what i wanted to without getting in my way. Sure it was not foolproof and i dont want it to be. I like JS just the way it is and I am grateful to it.
I personally don't like that Javascript has had to have a ton of work done on it to get it to the point of other languages that were better at their first release. It was just a ton of time spent on something that was weak to begin with.
If Javascript were better at the beginning, and this same effort was spent on it, it probably would be ruling the world, front and back-end, and be a really good language with great tooling around it.
There was a great amount of debate about nulls being a billion dollar mistake, but Javascript probably beats it in monetary damages by far.
Something wasn’t done right, right off the bat, thats grounds for not liking it, sure. But to dismiss it as immature despite it overcoming most (not all) of those flaws seems unfair.
I like it, some dont. I get it. All I ask is to not dismiss it.
Folks new to programming find these edge cases as a reason to not learn it. That irks me.
It has not overcome any of the flaws, we have just learned to work around them. They are still there and can bite you.
Some of us value our time and would like to improve our discipline. In other fields it's called being professional. It's a shame we care so little about it.
You've got me thinking now. Can you/anyone give me 3 solid cases where the flaw was in javascript and not the programmers understanding of the language ?
I can't. (Not at the moment at least).
Most of the times I got things wrong it was my understanding of how js works that was at fault.
I understand that Javascript will silently do something stupid and keep going if I accidentally call a function with an argument left off, but I'd still prefer to get an error message.
I understand that I need to use === instead of == to check if two things are actually equal, but I don't like that either.
It's not that you can't understand how the language works, it's that the language does some things that feel stupid when you're coming to it from any other programming language. Even if I can work around all of them it doesn't feel like I should have to when we have a lot of better planned programming systems, and that makes trying to get into js feel frustrating.
Of course the flaw is always in the programmer's understanding. Langauges do not manipulate or lie to you, they are what they are.
However, better tools and languages reduce your cognitive burden. The less mental context you have to work with the more you can focus on the problem at hand. If you have to constantly worry about language edge cases and odd behavior, it really detracts from being able to focus on the problem you are trying to solve.
There is a reason languages like TypeScript and Flow exist, they are helping to reduce this large burden JavaScript carries with it.
JavaScript is really great for small scripts (which is the use case it was designed for).
Anything beyond a few hundred lines starts to carry a lot more cognitive load. Not to mention that we are now building full fledged applications with tens of thousands of lines in this language.
> Anything beyond a few hundred lines starts to carry a lot more cognitive load. Not to mention that we are now building full fledged applications with tens of thousands of lines in this language.
Depends really on how much care was put into the application structure, mostly from the outset.
I've followed opinionated styleguides closely on some projects, and have also walked into other swamp projects that snowballed into something massive from a few snippets of jQuery. The difference between working on something that was intended to be maintainable from the start and something that evolved haphazardly is of course like night and day.
I still think it's more the people and approach than the tools.
> Anything beyond a few hundred lines starts to carry a lot more cognitive load. Not to mention that we are now building full fledged applications with tens of thousands of lines in this language.
> Browser differences in javascript by not having a good specification or strong governing body.
Its the browser implementation that was at fault. The ambiguity in specs was and is minimal to negligible for the past 8 years (since I started following). But like you said, not relevant today.
> Not having block-level scope despite convention in other C-like languages.
> Optional semi-colons.
Its a feature, not a bug!
> typeof inconsistencies.
Maybe. Never faced it.
> Another problem with JS changing so much is developers picking up the language at various points in that development.
What I see constantly changing is JS frameworks and preprocessors, not the language itself. Newer folks tend to learn some JS framework first before the language itself (just like I did) and the constant change can hurt and impede progress and confidence. The language itself has been well documented and forgiving in my experience.
So yeah, point taken. You do not like JS. I do. Let's make peace with that.
"it probably would be ruling the world, front and back-end"
So, what would be different about that? JavaScript does rule the world, front (definitely) and back-end (arguably, but there aren't a lot of contenders for the language that's more popular for new projects).
Most languages had major design flaws. Rubyists will gladly complain about how OO is bolted on in Python, Python users will gladly talk about how slow Ruby's interpreter was and how god awfully complex the syntax is. Both of them have limitations in their runtimes and are actually catching up to JS in some areas (see Python's adoption of async).
We can talk about how baroque CL is or how much Java sucked in 1995, how massively complex C++ is, etc, etc. Those arguments have been made for decades, though. JS is no worse than most languages in various ways, but people are pissed off because their chosen language isn't as popular.
Maybe that's a cynical point of view, but these criticisms never get past the most superficial concerns, so it's not obvious why people really care so much.
JavaScript and PHP are badly/barely designed languages, period; no amount of excuses and comparisons is going to change the fact. Anyone with a bit of experience in either Ruby or Python will tear their hair out when doing JS, because they know it doesn't have to be that difficult. These days it's looking more and more like C++ every day...
This is of course my personal opinion, but I think you're suffering from exactly what OP mentions. I'm not trying to be conflictive or anything, but this is in my experience the same argument that every language evangelist uses.
I started with C in my early teens (first book I found, lucky me) and I've gone through the VB, PHP, Java, Python, Ruby, and Javascript phases. Honestly I've seen great engineering in all those languages (maybe not VB) and those projects have all been easy and pleasurable to work with (maybe not Java). I've also seen hideous stuff that's a total sanity destroyer. At least for me the main contributing factor to language dislike is dealing with shitty code. Except Classic ASP... That stuff is poison.
I code in Ruby everyday and I think JS is a far superior language. Javascript has closures, modules and hoisting that complies and stores functions and variables before executing.
In Ruby code starts executing before everything is initialized making it unpredictable. Also JS is just so much smoother is composable. It's far superior to RUBY IMO
The features which make a language rise rapidly might just be different to the features that make a language "good".
PHP in particular is amazing for getting started at speed. I remember taking a HTML file and popping in a couple of lines of PHP in the middle. I still haven't found anything anywhere near that easy for making a server backed website.
You aren't the first person to think of this. It is otherwise known as Worse is Better[1]. Stuff that doesn't have all of that nice formalism but lets you get simple applications working without a lot of up-front training and boilerplate tends to be what people gravitate towards instead of "properly designed" languages.
I want my programming language to be predictable and easy to use. I'll "well design" my code, thats what I get paid to do. Type safety, yeah, never bothered me much anyway.
I agree, it sucks that js the only alternative in some cases. But hey, imagine if Java was the only alternative!
That says more about Java than Script though, and I've done enough of that to feel your pain. Coming from plenty of experience with sane dynamic languages (Common Lisp/Smalltalk/Clojure/Julia), it looks exactly like the madness it is. It's a difference in perspective, that's all. It's not about foolproof, it's about having any kind of intellectual integrity at all.
It does now (ES2015 modules) but it was standardized too late, so people created their own solutions, and now it's super hard to implement the standard over them. That's why nodejs isn't transitioning to ES2015 modules anytime soon (although they're working on it).
I agree, this post is super-b, but it also shows why JS is the mess everybody knows it is. When you use a function as a constructor, the function creates an object and assigns as its __proto__ the value of the function's 'prototype', which is an object with the class' methods and that has an attribute 'constructor' that points back to the constructor function... and all that... for what? What purpose has this over-complex dance of references? Before trying to justify the current status quo, let's ask ourselves "could it be done easily?"
The answer is a resounding yes. Javascript is a prototype oriented language (nothing wrong with that) who is ashamed of being prototype oriented and wanted to look object (class) oriented, and that's a shame.
And of course, we have ECMA, a committee whose motto is "let's not change any past error no matter how flagrant it is, let's add just another layer of painting over it". That's why we have to live with hoisting and var/let, and crazy type conversions that are an affront to every living neuron in the universe, and typeof which return useless values, and yes, two comparison operators because the first one was worse than wrong.
Full disclosure: I've been writing JS for pretty much as long as I can remember and currently do it professionally, and I'm speaking mostly to my personal experience with having used both of them personally and professionally.
The question is how often you get bitten in the ass by it, specifically as a professional rather than a beginner, and in my experience it's been very little with Javascript but quite often with PHP. Once you know a few things like the difference between == and ===, that undefined and null are different, etc., it's pretty easy to avoid the warts because the warts become obvious. I'm not going to argue that Javascript is well designed, it's really not, just that I rarely if ever run into the typical laundry list of gripes in such a way that it has a profound effect on my job.
And having ESLint backing me up doesn't hurt, either. But that's not technically relevant.
PHP, especially the older versions, contained many subtle traps you could easily fall into. For all of its flaws, I've never really felt the same about Javascript. More to the point, beginners are always going to stumble. It comes with the territory. I tend to focus my criticisms more on problems that knowledgeable programmers can stumble into accidentally rather than ones that are commonly met by new programmers, if that makes sense. The former seems like a far worse problem, because the former starts to touch (bear with me) "real" code.
Just as an aside, the biggest single pain point for me when I still used PHP (a lifetime ago, now) was the way PHP used to report missing quotes extremely inaccurately. Egads that was an awful bug. I hope they fixed that.
What it boils down to in my mind is, when I'm writing JS, I'm comfortable not having a linter available. I don't always feel the same way with PHP, because I don't feel like the traps are as easily avoided. I certainly don't think I'm some sort of Javascript guru, it's just that I don't have many problems with it in a purely practical sense when compared to PHP.
I think this is a fair way to read it. I have made my bones on ripping PHP and JS up and down, left and right; I didn't trust them as far as I can throw them. SPAs sucked because JavaScript sucked, and PHP sucks because its existence has put more frustrating work on my plate than anything else.
I still feel that way about PHP. ES6 and ES2017 changed my mind about JS, though, along with the eventual maturity of the stack: babel, eslint, good testing in Jest. Everything I always hated about JS totally does still exist in its bowels, that's never going to change. But the guard rails have gotten very good and more modern flavors of JavaScript have added a lot of stuff that makes life easier (strongly opaque modules, async/await, and arrow functions are probably my top three). The build ecosystem is still bonkers, yeah--but there's a baseline level of sanity that I can work with. I know there are still land mines in there, but they're flagged and mostly out of the way.
On the other hand, any time I'm stuck back in PHP, it is fundamentally the same stuff that has been sticking needles in me since I was in high school. Yeah, the language has advanced--but I'm not sure the general practice has advanced all that much, and the parts of the language that are problematic are right up in your face.
In my case, my problem is that I like clean languages, languages whose mental model I can keep in my mind. I found "== is broken, use === instead" a terrible way of designing a language. It should have been "== is broken, let's fix it today so tomorrow will be better for everybody."
I can program in JS, and sometimes I even enjoy it. I had a friend who liked snakes and had several as pets, even some poisonous. I prefer kittens.
It's hard for me to take these comments seriously unless you feel this way consistently across most other dynamically-typed languages -- at least it'd be consistent.
I've used most dynamically-typed langs at this point and I've run out of reasons to use something aside from modern Javascript if I would have originally used Clojure or Ruby in the past.
Though it feels sheepish to reward your low-effort comment with a response.
I still find a lot of reasons to use Ruby, though like you I spend a lot of time doing JavaScript in places I wouldn't have a couple years ago. (For a long time I've been anything-but-JavaScript, but I was also using JavaScript before it was cool--somewhere on a hard drive somewhere is a JavaScript implementation I wrote as a scripting layer for a game I was working on in like 2006...)
My experience with API design in JavaScript is that it still kind of sucks. It's not the worst, that wonderful spot goes to PHP, but it's distinctly harder to get something usable and maintainable done than Grape/Ruby. Probably worse than Flask/Python, too. The Swagger tools out there for JavaScript aren't very good and none of the lesser-used alternatives seem any better; maybe it's the stateful/metaprogramming-friendly nature of Ruby, but `grape-swagger` is really nice and nothing comes close in JS, at least not that I've found.
Data representation worries me, too. I have not yet found a decent `grape-entity`/`representative` library in JS (think a `grape-entity` or a `representative`). On top of that, SQL library support out there is pretty bad, Sequelize being the best I've found but much worse than Ruby's Sequel or even ROM. Sequelize is still frustrating and clunky.
I'm also uncomfortable dealing with money and financials in JavaScript, in part because of the lack of a BigDecimal/fixed class that I feel like I can trust (as I'm not really qualified to judge the implementations of the billion gems out there). A standard library I feel like I can trust is still out there, somewhere.
If all I have to do is plop out an endpoint, then JS (shouts, Express!) is as easy as it gets, and that's fine. But these days I need more, I want my tools to help me with it, and I don't really have time or inclination to build them, either.
If I'm missing any that are worth checking out, though, by all means, I'm very interested.
I don't like ORMs or abstractions like grape-swagger. I like working with the node-postgres client and knex when I need a query builder.
It sounds like if that's the sort of kit you want, then Ruby is for you compared to Clojure/Javascript.
What I do like about Javascript is that it's easy to write ad-hoc types via Typescript for my SQL functions to specify the shape of the data that comes from the database. I would never go back to something like Active Record that tried to make me canonicalize all of my data.
I have to wonder if these are more identity-level ecosystem differences.
I'm very confused as to why you don't care for "abstractions" like grape-swagger. Do you enjoy writing API client boilerplate?
As far as ORMs go, I'd certainly prefer not to use Active Record ones, but I also don't want to have to update my code when somebody else adds a field that I don't care about. My representations specify what I care about and how it should be presented to clients (for example, hashids rather than integer primary keys); I update them only when there's a new field that I care about. I can do this with functional mapping but the database boilerplate sucks more than Sequel does (it's a big part of why I've dropped ROM, though I much prefer it in theory). Computers exist to help me do less programming, not more, and what you describe is more programming for, to me, little benefit.
I thought your "real-world constraint" existed too. Then I had to keep track of thousandths of a cent.
When you have experienced the "no, a cent is no longer granular enough" problem, the conversion of DECIMAL(7,2) to DECIMAL(9,4) and the attendant code compatibility is something you'll appreciate.
Curious, for server side, why do you prefer JS over Clojure?
(I assumed by your comment that you would still prefer modern JS already knowing Clojure. Maybe I misinterpret?)
Right, I would generally prefer JS over Clojure on the server side these days. Or, rather, I would default to JS and then possibly disqualify it based on my needs (like team composition).
I spent over three years using Clojure and eventually learned how unimportant technical superiority is for most of my projects. For example, the first time I met a co-founder and they simply weren't interested in using Clojure. Well, that was easy.
JS has major upsides like ubiquity and I'm-already-using-it-in-the-browser and its simple concurrency model that aren't so easy to paint over.
I'm not saying everybody should default to JS like I do. But I think a lot of these avoid-JS-at-all-costs posts need to update their intel. For example, JS has pretty great static analysis compared to anything I've used in the other dynamically-typed languages. It's also one of the few where gradual typing actually caught on.
For all its upsides, its warts aren't any worse than things like the overuse of metaprogramming in Ruby or the aversion to FP in Python or the tooling dependencies of Clojure.
One issue I have with this JS tutorial is that it spends little to no time talking about FP, just OOP (functional vs object-oriented programming).
What text it does devote to Closures makes them sound like a "problem" to be worked around. Funny, I thought "this" was the problem (to be worked around, or avoided entirely whenever possible).
Class based languages such as Java do an excellent job of modeling how I thought about programming back in 1990. It's how we were taught in school, so as to be able to manage mutable data in a turing tar pit. (remembering a lecture about garbage collection, which essentially scoffed at the overhead...)
Having learned a good deal more about FP in the last 10 or 15 years (beyond the little bit of Lisp I did in an AI class back in the 80s), Javascript really starts to shine in many ways, whereas Java (and other [Simula67 subset] C++ derivatives) looks like the intellectual cripple in comparison.
I wish people would stop trying to turn Javascript into something more and more like C++/Java. Just stop, already. It was supposed to be like Scheme and/or Smalltalk, but The Management (marketing) got involved, and the rest is tragedy, er, history.
> ECMAScript is an object-oriented programming language, having concept of an object as its core abstraction.
This is technically correct but misses that Javascript is not OO in the way that many other languages are, but is instead prototypical in nature. That's an important distinction because creating long prototype chains in JS is a very bad and negative habit, where as the same behavior is absolutely fine in Java.
I've just been reading through this and it's surprisingly accessible to someone without a CS background.
Anthony Alicea's Understanding Weird Parts of JS on Udemy was pretty good at introducing some of these concepts and I would have thought most people working with JS would be interested in finding out what's below the surface.
True, I'm not much into client side programming, just learning and lectures like this or Axel Rauschmayer's[1] are gold sources to understand Javascript.
> "ECMAScript is an object-oriented programming language, having concept of an object as its core abstraction."
I'm curious as to whether or not this definition makes sense to other developers? ECMAScript does have a built-in "Object" data type, though I wouldn't say that this is it's "core abstraction". Further, firmly object-oriented languages, such as Java, seem to lack this abstraction. Perhaps I'm missing something in the definition?
It's a Prototype Oriented Language, a language where the inheritance chains follows objects. Although, in all fairness, Object Oriented programming should be called Class Oriented, and Prototype Oriented should be called OOP.
"object oriented" can mean a wide variety of things.
java isn't necessarily more object-oriented than other options. generally, i think when people say "oo", they're really just referring to nominal subtyping; probably due to the language's ubiquity (as well as c++ and c#).
this nominal subtyping gives rise to the hierarchical taxonomies of object-classes that are a quintessential characteristic of java, c# and friends.
The core notion is little-"o" objects, which are a collection of properties, which in turn are a collection of attributes.
There is also the big-"O" Object (sometimes called the "Object object," hah). This is a place to hang useful functions and also serves as the default prototype.
As many useful things as there are in ES2015 (and beyond!), it's probably worth pointing out a few "corporate" environmental constraints that might limit one to ES 5.1:
* IE11 isn't dead yet. MS still supports it.
* The "Nashorn" engine inside (Oracle) Java 8 only supports 5.1.
Scoff at them if you will, but some of us have to live with these things, and aren't using a transpiler.
Does JavaScript have some special definitions for delegation and dynamic dispatch? The definitions provided in the article appear to particularly relate them to inheritance - which is not the traditional definition applied to either term in object-orientation?
I think that the article is actually correct, because the reason why in other - mostly static, and better designed dynamic -languages, you knew that member functions were bound to the object being called is because that is how the functions were actually handled by that language's runtime. There is no such assumption in JS, so where in C# you explicitly design a delegate, the reverse is true here. You need to explicitly bind the function or declare the function as a property with an arrow function and capture the execution context.
The 3rd edition of Eloquent Javascript (including ES6) should be online next month. Marijn Haverbeke was fundraising and reached his target.
https://eloquentjavascript.net/3rd_edition/
This article is useless for the modern web development. Nowadays the essential is to know the nuances between Angular versions and how to defer a promise returned by chained observables.
You can get away with treating a JavaScript Engine as a black-box but understanding what is happening under the hood will make you better. It will give you a mental model to draw on when you run into some edge case that causes strange behaviour that is otherwise unexplained.
It is for those who already know frameworks, can hack something together and are interested in learning more. Having habit of learning things like this helps a lot in the long term.
Because saying "X is worse than Y" is not useful unless you provide reasons as to why you believe that.
Imagine being someone reading your post. What are they to think? "Oh, this person says X is worse than Y -- I'll go ahead and take their word for it, despite no justification"? That's them buying into an appeal to your authority.
Now imagine if you'd actually provided reasoning. "Oh, this person says X is worse than Y because Z -- Z is a good point, therefore this is useful!" How different.
Providing baseless opinions is not useful, which is why you got downvoted; and incidentally, it's the exact same reason why you should "care to elaborate".
It also clearly shows that Javascript is not the mess that it looks like from a beginner's perspective. Yes, anyone can create a 15-20 min video about how == and === can mess up stuff, how you cant just pass around a function with a this in it without being careful, how NaN is wtf, and all that jazz. But at the end of the day, stick to this language long enough and it works for you.