Why is Javascript so difficult and overwhelming to learn in 2017?

Validation Header

Why is Javascript, the language that drives the modern web (and more), so difficult and overwhelming to learn in 2017? Why will it likely continue to be just as difficult and overwhelming in the coming years? The short answer is, because learning Javascript doesn’t actually mean learning Javascript, a singular language. Rather, it really means learning all the frameworks, build tools, package managers, and everything else that has been created using this language.

People who refer to Javascript may not even be referring to the browser language most people think of. Javascript is now implemented as a system language, NodeJs and as a mobile language in libraries such as React Native. Javascript is in many places you wouldn’t expect and has become not just a language, but a diverse ecosystem of libraries that in some cases can be platform agnostic. This diverse use of Javascript, however, is exactly the problem. Learning just the language isn’t terribly useful on its own. Like in learning anything, Javascript needs to be taken step by step as attempting to ingest all the various libraries and intricacies of the ecosystem can quickly become overwhelming.

A Brief History

Javascript has a rich history, beginning with its inception in 1995 to its “boom” in the early 2010s. Initially, Javascript was developed by Brendan Eich in just under 10 days for Netscape, now Mozilla Firefox, under the name Mocha and then Livescript. At Netscape developers realized they needed a “glue language” to make the web even more dynamic. Many developers were using Java applets to create dynamic content on their websites, but many at Netscape felt that Java was not the right tool to make the web dynamic. Unrelated to Java, Javascript was allegedly named “Javascript” to attempt and feed off of the Java language’s popularity to increase market exposure.

Microsoft, realizing a similar need released their own reversed engineered version of Javascript in 1996 called JScript. However, the implementation greatly differed from that of Netscape’s Javascript, making it difficult for developers to create websites that worked consistently in both browsers. This led to the use of “best viewed in (x)” to denote which browser the website would work best in. This was arguably the beginning of the infamous browser wars, which still continue to this day.

Not long after Microsoft’s 1996 release, Javascript became standardized under ECMA-262. This lead to several popular implementations of the standard set by Javascript, which remains the most popular to this day, followed by Microsoft’s JScript and ActionScript. Although Microsoft’s original implementation of ECMA-262 was technically valid, it eventually began to diverge from the in-progress proposals for ECMA4. It became clear that they had “no intention to cooperate or implement proper JavaScript” (Wikipedia, JS History). This divergence continued to be problematic for the next decade or so. It wasn’t until 2012, when Microsoft released Internet Explorer 10, that their Javascript implementation became more standardized.

Learning Javascript

Javascript is easy. It’s a surprisingly forgiving language compared to Java or C++. Many of Javascript’s roots come from Java and C, however it remains far less verbose than Java, and much more dynamic than C. Unlike these languages, Javascript offers a loose typing system and hands off memory management. These characteristics enable the user very quickly to pick it up and start coding. Its type system is so dynamic that it allows you to change a variable to an entirely different data type without issue. You can even easily add a Number type with a String type, although this can sometimes result in an odd translation - but the point is, you can do it without issue. As long as you’ve got a basic command of coding, it’s not very difficult to quickly acclimate to Javascript.

Being this easy does have its disadvantages. Because it’s so easy to learn there is an over-abundance of poor Javascript developers - people who think they have acquired the language because of its seeming simplicity. Forgiving languages, such as Javascript allow anyone to code without having much knowledge or skill in problem solving or actual programming. It’s at this point that the difference between programming and coding becomes apparent and worthy of our attention. Anyone can code, Javascript is proof of this, but not everyone can program. Programming requires problem solving skills and the ability to think critically about the problem at hand, while coding is simply the act of writing arbitrary code (Huffpost). Coding without the necessary problem solving skills often results in programs which are hacked together with little thought and turn out to be messy to maintain and a nightmare to use.

Why is Javascript so difficult if coding with it is so easy?

While the language is easy to understand and write, there are several core items which significantly affect the language’s usability. The first and most omnipresent example of this is that Javascript implementations differ from browser to browser which creates slightly different APIs that need to be accounted for. The second issue, is the large number of frameworks and libraries that are a necessity to any large-scale project. Unfortunately, many of these libraries require a steep learning curve. Lastly, there are multiple language standards which are actively used. These various versions all include significant feature changes, many of which completely change how Javascript is written, making it so that a developer has to essentially relearn the language with each new version.

The most significant issue, which has arguably shaped the development of Javascript since it initially gained popularity, is the multiple implementations of the Javascript run time. Unlike other languages with competing versions and API levels, there is no control over which version the user is going to use This is because each browser has a slightly different implementation which may have different APIs and slightly different language behavior. For instance, IE originally used attachEvent rather than the standard addEventListener which meant that for scripts to work in IE, you had to tailor your code to function in that browser. (Stackoverflow) There are many other small differences which require different code snippets to allow the same functionality across browsers.

Where the problems originated

In more recent years, there has been much more consistency between browsers which makes development far simpler thanks to the standards put together by ECMA International and standardized under ECMAScript or ES-year (ES2017 or ES8) for short. Other than the case of Internet Explorer, most differences in the Javascript implementation come from experimental features which have yet to be completely implemented. It’s important to be aware of these inconsistencies because they shaped how the language and community rapidly grew in size and popularity. These differences made way for jQuery, a method of flattening out the Javascript API so that the same code would work on any browser reliably.

jQuery is said to be both a blessing and a curse. There has always been a lot of controversy over its use (see this Quora answer). While it’s fairly powerful and drastically changes much of the normal syntax of Javascript, it also led to a phenomenal amount of “spaghetti” code (messy code that jumps around making it very difficult to follow) and poorly designed work flows. One large criticism of jQuery and Javascript itself is their considerable use of these callback functions; functions that are called after some task has finished. jQuery, in particular, uses a large amount of callback functions. This is the primary contributor to “spaghetti” code because they enable the code to jump around, similar to a modern goto function, which can be very difficult to follow, thus leading to slow and ugly code if you aren’t careful. jQuery enabled even the most inept coder to make beautiful websites with ease, even if they are a nightmare to maintain. After jQueries’ huge rise in popularity, developers set out on a mission to create libraries that are cleaner, easier, and more efficient frameworks and libraries.

All of the libraries!

The current climate of Javascript libraries and tools is expansive and can be incredibly overwhelming. More than just the libraries, a plethora of tools exist that are often required in order to use the libraries, forcing an ever steeper learning curve. The satirical article How it feels to learn Javascript in 2016, paints a painfully precise image of what it’s like to learn Javascript, even in 2017. Much like technology as a whole, Javascript development is extremely rapid. New libraries and frameworks are a frequent occurrence from developers, resulting in a very saturated market full of libraries that may or may not be useful. Many developers realize a need for a specific use case in existing libraries, leading to the development of plugins. Although the market is very saturated, many options from which to choose exist and thus there is rarely a need to “reinvent the wheel.” On the flip side, this saturation also quickly leads to new developers being overwhelmed and unable to choose a library to use.

In order to build a fairly simple web application, one must first have an understanding of a number of steps. In this case, according to the aforementioned article, ReactJS is the library of choice. Before being able to use React, it first must be installed. To ensure that other developers can also use the project it’s ideal to use NPM, or Node Package Manager (Yes, that’s right, Javascript has its own package manager). NPM will save package environments so that it can stay consistent across various development environments. Once NPM has been learned, which arguably is the easiest part of all this, it’s time to move on to installing React - however react is split up in such a way where the library is very isolated and if you wish to use it with HTML you also install “react-dom” which creates bindings from react to the DOM (document object model) or HTML and allows for manipulation of HTML. Great! So now you can write your HTML! Wrong. While this isn’t the only option, React uses a special syntax for describing DOM called JSX, or Javascript syntax extension, which essentially just adds the ability to write HTML directly in the Javascript so that it can later be transformed into Javascript objects. Alternatively, you can use Javascript version 6 (Or ES6) template syntax, however JSX is more standard when using React. As Jose Aguinaga so eloquently explains “It’s 2016. No one codes HTML directly anymore.” The basics for creating your react application are now in place - but wait, there’s more!

Aside from React, a number of other libraries can be used, including, to list just a few, AngularJS, which is a very popular Model View Controller framework. Alternatively BackboneJS offers a similar Model View Controller workflow. Of course, there’s ReactJS which takes a “reactive” approach, which means that it will automatically update the UI as variables change and will only update parts of the DOM that need updating, rather than rerendering an entire component. My personal favorite framework is VueJS, which is quite similar to React, however, it offers some consistency that React doesn’t have as well as some other behind the scenes design differences. Some libraries even completely change how Javascript works, such as Coffeescript, which aims to simplify a lot of common tasks, very similar to Kolten and Java. Another popular library is Typescript which, you guessed it, enables strong typing in Javascript. Because of how these two particular libraries function, by transpiling down to normal Javascript, they will work with many existing frameworks. This, however, does lead to an interesting, and problematic issue - many frameworks are written to use a specific version of Javascript, more often than not (similar to Typescript or Coffeescript) the average browser does not support these versions directly.

Too many versions

Like any piece of software (and yes, languages are software in and of themselves) new versions are frequently released with new features and fixes. Javascript, is no exception.However unlike most software, Javascript changes must be implemented within the browser and cannot simply be installed to a user’s computer. Most browsers do not fully support any version of Javascript past ES5 (2009) causing some issues when trying to develop using ES6+.

In order to avoid confusion, it’s important to realize that Javascript and ECMAscript are slightly different - ECMAscript is not actually a language, but rather a standardized specification of the language. ECMA specifications describe how Javascript should be implemented in extreme detail to ensure that the language runs identically in all implementations. The 2017 version of ECMAscript is an incredible 885 pages. The most significant update was made in 2015 when the 6th version was published. It added significant syntax and functional changes. The most significant of these changes were Class and Modules which allowed for easy creation of objects in a more standard way as well as object extension. To allow for backwards compatibility, however, they are defined semantically the same way as ES5. Additionally, ES6 added iterators and for/of loops (for( x in list) rather than for(var i=0; i < list.length;i++)), Arrow function syntax for anonymous functions, promises to clean up traditional callback issues, number and math improvements, and much more. ES7 and ES8 improved upon a lot of these changes, but ES6 is still the syntactic basis.

Back to libraries

Most web projects have two goals aside from their primary functionality. The first goal is to ensure that the maximum number of users can easily use their project and the second is that it can be fast for their users no matter where they are. The first issue is brought about by the multiple versions of Javascript and adds another layer of complexity. To make sure that projects can run on any browser, most projects use transpiler. A transpiler translates one version of Javascript to another. Most commonly, it will translate ES6+ to ES5 to enable browsers to be able to read the scripts. One of the more popular and robust transpilers is Babel. Its popularity is largely attributed to its expansive range of capabilities. Although one of the primary translation jobs is to translate from one version of Javascript to another, it’s also able to do things such as Polyfill, which is simply a shim, a method of enabling compatibility, for a outdated browser APIs. to allow for new features to work on older browsers, as well translate JSX, or even your translations. Clearly, Babel and other similar translators are very powerful and necessary, but this does create another problem: Because the code being written will not work as is, it has to first be translated to work in the browser. Manually launching Babel to translate after each change is possible but cumbersome. Additionally, debugging translated code may render unexpected results as the code will look different from what was originally wrote. So then, how do you create a build environment that will automatically translate your files in such a way that allows easy building and debugging?

Building & Bundling

The second complication with modern libraries relates to packing and building. As previously mentioned, part of a project’s goal is to be fast and because loading large files over the web is going to be slow we need a solution to make those files smaller and few files overall. Similar to the build issue with Babel, we need a system to enable not just transpilation, but also a system to help shrink file size. Thus, the next large learning curve has to do with elements such as the bundler, packer, transformer, tasker. These applications are designed to run tasks that bundle (combine), minify (shrink), transform (translate), and much more. The first task runner I was introduced to was Grunt - a simple command line utility that allows the user to define tasks that run when called. Grunt had many third party plugins to enable simple tasks such as copying and concatenating files or to allow far more complicated tasks such as translating your Javascript or “uglifying” your Javascript code into an obfuscated and minified version. Although Grunt can do a lot, it’s very cumbersome to set up and doesn’t allow for a very robust build system. As the need for all these tasks increased, more modern systems were created such as Browserify or Webpack, both of which are still very popular.

The Browserify and Webpack systems are quite complicated and extremely robust, much more so than Grunt. But they also serve different purposes even though they lead to a fairly similar result. Browserify allows developers to write Javascript as if it was NodeJS. This allows developers to use statements such as require(‘library’) rather than using the ES6+ import ... from ... statement. Browserify also adds multiple shims for popular Node functionality such as crypto, util, and more. This is aimed at making Javascript development easier for folks who are more comfortable with Node. In addition, Browserify allows custom processing such as transpliation, bundling and automated testing. Though Browserify allows for NodeJS style programming, many people use it just as a processor for their projects. Webpack on the other hand doesn’t have the specific use case that Browserify does, translating and shimming Node functions. While this could be easily added to Webpack, it’s not there by default. Webpack is much more generalized and is designed to process “simply” as a bundler. I say simply in quotes, because it’s capable of so much more.

Going back to “Wait! There’s more!”: In the case of ReactJS (but also available in many other libraries) there is a set of scripts that enable a webpack pipeline automatically. Of course, this is another thing you have to learn, but the set of scripts provided are quite helpful at giving a comprehensive setup with minimal work required. The configuration provided does quite a bit. To start, it creates a pipeline of basic translation - taking all your files and translating them into ES5 Javascript as well translating the JSX or any other special syntax such as typescript into the appropriate format. The next step of this pipeline is to bundle all of the necessary code into a single Javascript file. This includes all the code you wrote, as well as any libraries you are using. Combining all these files allows the browser to make a single request for all the code rather than adding the extra overhead of requesting multiple files. Along with bundling everything, the system will often obfuscate and minify the bundled Javascript to make an even smaller file. Minifying generally means removing any whitespace in the file, as those characters take up a considerable amount of space. Obfuscating on the other hand, means renaming variables from their presumable multi-character names to incremental names such “a” or “aa” after the entire alphabet has been used. Another major feature of many of these systems is the presence of development servers. Not only do these serve your application on a local web server, but they also often provide debugging functionality such as source mapping, so that you can debug your code without looking at the translated and minified code, as this will probably look very different from the code you wrote. It also hooks into the library you use to help you debug internal states that the library may keep track of internally. Luckily, you only really need to have a deep understanding of these systems if you need to create special processing, otherwise a lot of it can be done for you.

Okay, but this is still overwhelming

Given all of this complexity, how on earth is anyone supposed to break into this complicated and highly stacked environment? Everything requires you to know something beforehand and there’s so much to learn before you can even get to the actual library you want to use. The answer is simple, start small and build up. If you don’t know how to code in Javascript, start by learning it - the language itself is really pretty easy to learn. After that, you can take a look at ES6+ and what new features it has to offer. Maybe pick up NPM and a basic processing utility such as Grunt to translate your ES6+ code to ES5. After that you can start playing with libraries and using systems like webpack. Learning all this will always be easier if you break it down. Jumping straight to the React + Redux application is going to be extremely overwhelming. The first time I went to learn React I dropped it after a week because I simply couldn’t grasp everything all at once as I hadn’t learned about Babel or ES6+. Thankfully, many tutorials and utilities exist that make the build up much faster (See below for a list of guides to popular libraries). Tools like react-create-app and vue-cli create boilerplate projects so you can jump in more quickly. And due to the popularity of Javascript these days, finding tutorials is a breeze. Taking it one step at a time and using your resources appropriately will lead you to a successful career in Javascript.

Works Cited

Standard ECMA-262, www.ecma-international.org/publications/standards/Ecma-262.htm.

“Browserify.” Browserify, Browserify.org/.

Chapter 4. How JavaScript Was Created, speakingjs.com/es5/ch04.html.

“Different Browsers Have Separate Implementation of JavaScript.” Different Browsers Have Separate Implementation of JavaScript - Stack Overflow, stackoverflow.com/questions/16410425/different-browsers-have-separate-implementation-of-javascript/16410495#16410495.

Foundation, Node.js. Node.js, nodejs.org/en/.

“JavaScript.” Wikipedia, Wikimedia Foundation, 15 Dec. 2017, en.wikipedia.org/wiki/JavaScript#History.

Kambona, Kennedy, et al. “An Evaluation of Reactive Programming and Promises for Structuring Collaborative Web Applications.” Proceedings of the 7th Workshop on Dynamic Languages and Applications - DYLA ‘13, 2013, doi:10.1145/2489798.2489802.

Prottsman, Kiki. “Coding vs. Programming – Battle of the Terms!” The Huffington Post, TheHuffingtonPost.com, 12 Apr. 2015, www.huffingtonpost.com/kiki-prottsman/coding-vs-programming-bat_b_7042816.html.

“React.” A JavaScript Library for Building User Interfaces, reactjs.org/.

“AddEventListener Not Working in IE8.” Javascript - AddEventListener Not Working in IE8 - Stack Overflow, stackoverflow.com/questions/9769868/addeventlistener-not-working-in-ie8#9769930.

“Why does jQuery suck so much?.” jQuery/Javascript - Why does jQuery suck so much? - Quora, https://www.quora.com/Why-does-jQuery-suck-so-much.