No More Surprises: Going Deep with JavaScript
Learn how to stop being surprised by your code
Learn how to stop being surprised by your code
In the initial 3 months of my first and current programming job, I read and wrote more JavaScript than ever before. During those 3 months, as I fixed bugs and implemented new features, I encountered several JavaScript surprises.
A JavaScript surprise is any observed behavior in executed JavaScript code that surprises the onlooking coder even though the observed behavior is normal. In other words, the coder is surprised by some element of JavaScript that is operating as it was designed to operate.
Here are some examples of JavaScript surprises — although, they are only surprises to the yet-to-be-informed coder. I haven’t thought of how these might happen in practice, but I have experienced other subtler surprises due to JavaScript’s Type Coercion rules.
During those early months, figuring out why an error occurred and fixing the error was enough for me. I didn’t feel the need to spend more effort than was necessary to deal with the problems at hand. Additionally, I was among those of us who would say, “Oh, JavaScript did something weird.”
The bug that changed everything
I had enough JavaScript surprises when I encountered a certain bug. Let’s walk through what happened.
I don’t remember the exact reason why dateString evaluated to an undefined value. But, we can imagine that I tried to access the field of an Object on which that field did not exist. Doing so would result in an undefined value.
The code snippets show that the moment function will accept the undefined argument and return a valid Moment object of the current date.
At the very least, I expected that passing undefined to the moment function would result in an invalid Moment object. Instead, I got silent approval and a failure waiting to happen.
With my then understanding of JavaScript, I couldn’t see the behavior observed in the code above as predictable or reasonable. Feel free to read through these comments or the code on GitHub to understand why the particular behavior was observed.
The gist (pun intended) is that calling a JavaScript function with an undefined argument is mostly the same as not passing the argument to the function. When the moment function was invoked with the undefined argument, it was as if the argument was never passed. This led to the eventual evaluation of a new Date(Date.now())
expression to the current date.
The moment.js developers could prevent this behavior by inspecting the Arguments object present in JavaScript functions, but they don’t consider doing that a good practice. The Arguments object contains the value of the arguments passed to a JavaScript function. Feel free to read more the Arguments object here.
As is evident from the GitHub comments, other developers were also thrown off by this unexpected behavior. But, I came to the conclusion that my confusion was rooted in a gap in my JavaScript knowledge, as opposed to a shortcoming in the moment.js library’s design.
I felt that my mental model of how JavaScript worked was inadequate, and I did the only thing I could think to do: I went deep, because I never wanted to be surprised by my code again.
Deep JavaScript Foundations
Code2040 gifted me a subscription to Frontend Masters, which I then used to deepen my understanding of JavaScript, starting with Kyle Simpson’s Deep JavaScript Foundations course.
Working through the materials in this course and watching Kyle’s clear explanations and demonstrations was enlightening to me. I was exploring the fundamentals of JavaScript in a way I hadn’t before. Then, I began to wonder about Kyle’s command of the JavaScript language. It seemed so effortless.
Would I have to be a professional with over a decade of programming experience to use and articulate my understanding of JavaScript with such precision?
Before continuing, let us take a look at how I’m guessing many of us learn programming languages. This is complete speculation base of my own experience learning programming languages and the experiences of a few others whose learning experiences I have some insight into.
How we learn programming languages
Although we each have our different approaches to learning programming languages, I suspect there are some common elements in our approaches.
Perhaps we begin by learning the basic syntax, grammar, and key constructs of the language, then we try to use the language to do something relatively simple. If we are not first-time language learners, we attempt to do things we have done using programming languages with which we are more proficient.
Furthermore, after we’ve understood the basic syntax, grammar, and key constructs of the language, our intuitions set in. We begin to use the language with confidence, knowing that we can rely on information sources such as Google and Stack Overflow for anything we missed.
When we encounter something unexpected, we will do a bit of research, understand what’s going on, fix whatever issue we had, and tuck away that knowledge, perhaps never to be surprised by it again.
But, what if we had spent more time with the fundamentals of the language, experimenting with its peculiarities, learning the language more deeply, and reveling in the learning process?
No more surprises
I’m sure a lot of Kyle’s knowledge that came from professional experience contributed to his mastery, but I’m inclined to think that a big part of his mastery is as a result of the extra time and effort he put into learning JavaScript so deeply.
He does what is counter-intuitive to so many of us. He reads the JavaScript manual. More accurately, he reads the ECMAScript® Language Specification.
Many times throughout the course, Kyle references the Language Specification to illustrate that much of what we think is strange about how JavaScript works is simply the specified rules of the language. There is nothing weird or magical going on.
If we take the time to truly learn JavaScript, then we will encounter less JavaScript surprises.
Final Thoughts
The main idea behind investing the time to learn JavaScript deeply by studying the ECMAScript® Language Specification isn’t limited only to JavaScript.
Whatever programming language(s) you have chosen to master, there is a definitive document somewhere that describes its rules of operation. Find it and study it. In my case, I spend time on the ECMAScript® Language Specification and the Ruby Docs.
In truth, we’ll never stop having surprises. There’s too much information for us to take in and process. But, we can do our best to get the knowledge we need to be surprised less often. We should take each surprise as an opportunity to go deeper.
To dismiss a strange-at-first-glance behavior in our tools as something weird and not trying to understand why things operate the way they do is to choose to remain ignorant. And, that is unacceptable (I’m talking to myself here.)
As we wield our tools to build systems that people rely on, we have a responsibility to wield them with mastery and with care.
Shout-outs
- Thank you, Code2040, for gifting me a subscription to Frontend Masters.
- Kyle, you are an amazing teacher. Thanks for sharing, and keep up the good work.
- To the moment.js developers and contributors, you have created a tool that makes it easy to work with dates. Thank you.
Resources
Here are some resources you can use to learn JavaScript well.
- [Free] ECMAScript® Language Specification
- [Free] Mozilla Developer Network (for JavaScript)
- [Free + Optional Paid Version] You Don’t Know JS
- [Paid] Frontend Masters