What is Java Script ? What is modern JavaScript ?

JavaScript is a programming language that first appeared in 1995[1] to give browsers their first type of smart functionality. At the time, web browsers were in dire need of some type of programming language, because without it, browsers acted as 'dumb' consoles that required to constantly communicate with remote web servers to change their workflow. With programming language support, it became possible for browsers to execute actions locally & dynamically -- on a user click, a mouse hover or key stroke -- without the need to constantly communicate with a remote web server.

Thus the first browser scripting language and first JavaScript generation was born. In computer science, a scripting language is a programming language whose code blocks are interpreted until they're run, which means JavaScript was designed to avoid an explicit compilation step from its source code state (i.e. when a person writes it) to its machine code state (i.e. when a machine interprets it), making it all the more appealing for simpler and faster web development.

Web page events & DHTML

A distinguishing characteristic of this first JavaScript generation were events on web pages. At the dawn of the web, everything delivered to browsers was web pages structured with HTML (Hypertext Markup Language), leaving no way to perform further activity once the web page was delivered. JavaScript code opened the door to a major breakthrough in dynamic behavior, because a web page could now be accompanied by programming logic that was executed on a user's browser.

With JavaScript code, it became possible for a user loading an HTML page...hovering over an image...clicking on a title to further trigger logic like presenting a message...changing the actual image...changing the underlying text all without the need to contact the origin server where the HTML page came from (i.e. everything was done locally). Take a look at the HTML page example in listing 1-1 -- which is perfectly valid to this date -- illustrating the use of events.

Listing 1-1. Web page JavaScript events: onload, onmouseout, onmouseover & onclick
<html>
<body onload="alert('Welcome to the page');">

  <img onmouseout="changeImgSrcSmall(this)"
          onmouseover="changeImgSrcLarge(this)"
	  src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/240px-JavaScript-logo.png" />

<h1 onclick="this.innerHTML = 'Hi, this is a JS click event!'">Click on this text!</h1>
<script>
function changeImgSrcLarge(id) {
  id.src =
    "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/480px-JavaScript-logo.png";
}

function changeImgSrcSmall(id) {
  id.src =
    "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/240px-JavaScript-logo.png";
}
</script>
</body>
</html>

See the Pen Web page events - Modern JS by D Rubio (@modernjs) on CodePen.

If you click on the 'Run Pen' button on the right side, you'll notice the first thing the HTML page does is present the pop-up message 'Welcome to the page'. This message is triggered by the JavaScript onload event -- associated with the loading of the HTML page -- declared in the HTML <body> element. The onload event is linked to execute the built-in JavaScript alert method which is used to present pop-up messages.

Next, you'll see an HTML <img> element declared with both the JavaScript onmouseout and onmouseover events. The onmouseover event is triggered when a user passes his mouse pointer over the <img> element, while the onmouseout event is triggered when a user moves his mouse pointer away from the <img> element. In both cases the events are linked to custom JavaScript functions seen at the bottom of the HTML page which change the <img> element src attribute. In summary, what these events and JavaScript code do is change the image source when a user moves his mouse pointer over and away the HTML <img> element.

Finally, you can see an HTML <h1> element with the JavaScript onclick event which is triggered when a user clicks on an element. In this last case, the onclick event is linked to inline JavaScript which alters the element's innerHTML attribute which corresponds to the element's HTML content (i.e. the one surrounded by <h1> and </h1>).

As you can see with this example, this ability to mix and match events with JavaScript code gave way to a rich mix of possibilities for web pages. It became possible to perform mathematical calculations, visual effects and deliver an overall better user experience, because it was no longer necessary to contact a web server to change a browser's state.

One of the first formal names these JavaScript techniques received was DHTML (Dynamic HTML). DHTML was classified as anything that combined HTML, JavaScript and CSS (Cascading Style Sheets) with the purpose of generating dynamic effects (e.g. animate text, rollover buttons, show/hide elements) based on a user's actions (e.g. mouse click, hovering or pointing the mouse over elements). In fact, to this day there are still sites that run and even distribute DHTML[2] and are perfectly compatible with the latest browser versions.

Although DHTML was a step forward over web pages without JavaScript code, as web page expectations grew it became less than ideal. DHTML's biggest flaw was it required the entire web page payload (i.e. JavaScript code & structured data) to be delivered in one step, with any additional payload requiring to get a newly generated web page from the origin web site yet again.

As the web grew -- with e-commerce, dynamic HTML content & web game development coming into the fray -- the expectations on browsers also grew and with it those of JavaScript. Suddenly, the first JavaScript generation that delivered 'modern' functionality for its time, started to appear a little rough. So JavaScript changed, the JavaScript language itself got a facelift like other web development languages (e.g. HTML 5, CSS 3), a series of other techniques emerged to make JavaScript more powerful and JavaScript libraries were created to avoid having to reinvent the wheel for everyday JavaScript tasks.

AJAX & DOM

Starting in 2004, JavaScript usage underwent a major shift with a technique called AJAX, an acronym for 'Asynchronous JavaScript and XML'. AJAX brought a new era of web pages capable of updating dynamically without any apparent communication with their origin web site. Of course, in the background a browser established communication with its origin web site again, except it was now done asynchronously via JavaScript. In this manner the origin server responded with new data -- in XML or JSON (JavaScript object notation) -- that was then integrated into the web page in a transparent way (i.e. without a full-page refresh).

AJAX became the norm for data intensive web pages (e.g. Maps and Email) where it was unfeasible to deliver the entire payload in one step or for web pages where constantly making full-page refreshes resulted in terrible user experiences. But the wide use of AJAX in all but the simplest of web pages, brought to light a series of problems that affected web pages and JavaScript code since its inception.

The first was JavaScript as a language was severely fragmented, mainly due to the browser wars[3] and the shift to support both web and mobile applications. The browser wars was a time of fierce competition between browser creators to dominate the market through 'bigger & better' browser features. This in turn led to half-baked or innovative JavaScript features that only worked with certain browsers. This fragmentation meant the same JavaScript code didn't necessarily work as expected across all browsers, leading to increasingly complex JavaScript designs needed to make web pages work equally across multiple browsers. Adding to the fragmentation, was the need to support JavaScript across many browsers, not just those on desktop computers, but those used across web and mobile devices (e.g. smartphones, tablets).

The second issue was JavaScript relied on the DOM (Document Object Model) to access and navigate the structure of web pages. There's really no quick way to explain the DOM[4], but suffice to say you already saw a little bit of the DOM in the previous web page events example in listing 1-1. All web page events (e.g. onload, onclick) are technically known as DOM events and a web page's HTML elements (e.g. <img>, <h1>) are technically known to a browser as DOM nodes which have DOM methods & properties (e.g. innerHTML). So writing JavaScript code required a deep understanding of the complex scheme of conventions and methods used by the DOM. With AJAX becoming all the more common for web pages, the DOM simply represented another adoption hurdle on top of JavaScript fragmentation.

To alleviate these last problems, web pages making heavy use of JavaScript relied on libraries to both standardize JavaScript behavior across browsers and make it easier to update web pages without direct use of the DOM. In this area, the jQuery JavaScript library -- created in 2006 -- established itself as the most popular choice for this purpose, which to this date is among the most used JavaScript libraries.

jQuery

The jQuery JavaScript library hit critical mass because it solved a major JavaScript pain point. It guaranteed the same JavaScript code could work across all major browsers and it also provided a more natural way to access and navigate the structure of web pages compared to the DOM. In addition, with jQuery's wide adoption, it also led to a flourishing ecosystem of plug-ins and sub-projects (e.g. jQuery-UI) based on jQuery which made its value proposition even more attractive.

But as explosive as jQuery's usage has been to date, jQuery is still rooted on foundations from early web page design practices. The following example in listing 1-2 illustrates a web page with jQuery's main functionalities.

Listing 1-2. Web page with jQuery
<html>
<body>
  <h4>
    <button class="continue" id="button-action">Blank</button>
  </h4>
  <div id="banner-message">Jquery 101!</div>
  <h4>
    <button id="ajax-call">Click to update message via AJAX</button>
</h4>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
  console.log("ready!");
  var bannerMessage = $("#banner-message");
  // DOM Traversal and manipulation
  $("button.continue").text("Click to hide " + bannerMessage.html());
  // Event handling
  $("#button-action").on("click", function (event) {
    bannerMessage.toggle(function () {
      if ($(this).is(":hidden")) {
        $("#button-action").text("Click to show " + bannerMessage.html());
      } else {
        $("#button-action").text("Click to hide " + bannerMessage.html());
      }
    });
  });
  // AJAX
  $("#ajax-call").on("click", function (event) {
    $.ajax({
      url:
        "https://cors-anywhere.herokuapp.com/https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=JavaScript&format=json",
      success: function (data) {
        console.log(data);
        bannerMessage.html(
          "There are " +
            data.query.searchinfo.totalhits +
            " JavaScript related articles on Wikipedia."
        );
      }
    });
  });
  });
</script>
</body>
</html>

See the Pen jQuery 101 - Modern JS by D Rubio (@modernjs) on CodePen.

The first important aspect of the jQuery example in listing 1-2 lies in the HTML elements (e.g. <h4>, <button>, <div>) being declared separately from any DOM events or JavaScript logical actions. Notice the HTML elements in listing 1-2 have no inline events (e.g. onload, onclick) or JavaScript functions declared directly in them, unlike the HTML elements used in the previous web page events example in listing 1-1.

This design is underpinned on the fact that HTML elements were originally conceived for presentation purposes (i.e. how to display a web page) and not on how to react to dynamic actions (i.e. a user clicking or hovering over an element), hence both HTML and JavaScript are separate. This separation requires the use of references to interconnect HTML elements with their JavaScript code. As you can see in this example, the various HTML elements all contain an id attribute that's used for identification purposes or a CSS class inside the class attribute that can also be leveraged for identification purposes.

Once HTML elements have identifiers, it's possible to access them for the purpose of manipulation. Toward the bottom of the example and wrapped in the HTML <script> element, you can see jQuery methods are prefixed with a $ symbol, which is the default convention for jQuery methods. For example, $(document).ready() -- that wraps all the logic -- defers JavaScript execution until the HTML document & DOM is ready. Once the HTML is processed, jQuery methods like $("button.continue").text() and $("#button-action").on() specify actions -- set text(), do on() event -- applied to HTML references declared in $(""), such as button.continue to indicate the HTML button element with CSS class continue or #button-action to indicate the HTML element with id="button-action".

Notice how all the JavaScript actions in the example update the <div id="banner-message"> element when something happens in other HTML elements. In addition, look at the last JavaScript declaration which is an AJAX call -- provided by the jQuery built-in $.ajax method -- that also lives separately from its HTML element and relies on many references to do its work.

Now let's take a step back and look at the good, the bad and the ugly of this design in listing 1-2. The good part is the design is simpler and cleaner than using plain DOM. With jQuery, event handlers and logic are no longer sprinkled around with HTML elements, but instead are clearly separated. Another positive aspect of jQuery is how it accesses HTML elements. Instead of having to work directly with DOM methods and properties (e.g. getElementById(), parentNode(), childNodes) that are difficult to master, jQuery supports simpler and more powerful methods to access HTML elements (e.g. by HTML element type, by id attribute value, by CSS class attribute value).

The bad part of jQuery's approach is that it can become overly complex to decipher and debug web pages with dozens or hundreds of elements & actions. So for example, it isn't the use of one or two AJAX calls in this format that presents a problem, but rather it's the use in web pages that require dozens or hundreds of AJAX interactions, where the management of references, data updates and error handling in this manner can quickly become difficult to understand.

The ugly part of jQuery's approach comes from the difficulty to express relationships between HTML elements and their actions. Notice how the example creates a reference to the <div id="banner-message"> element which is then used across the various JavaScript event handlers. The ugliness here stems from the fact that each of the JavaScript event handlers needs to be associated with a reference to the HTML element, instead of the HTML element being associated with JavaScript event handlers and related HTML elements that influence it -- in other words, all the actions associated with <div id="banner-message"> are spread out, instead of being grouped in a single location.

As web applications continued their evolution, newer and larger demands were placed on this kind of design. Single page applications (SPA) became a common theme with every functionality under the sun packaged into one page, smartphones took over as the most popular device to access the web and real-time web functionality became an almost default expectation. So once again, that 'modern' JavaScript of yesteryear started to appear dated. JavaScript components made their appearance to ease the creation of more complex JavaScript UI (User Interfaces), JavaScript libraries soon became full-fledged JavaScript frameworks and the JavaScript language became so limited for certain functionalities, that entirely new languages came into existence that ended up being converted into JavaScript!

JavaScript components

Components are an old concept in software engineering based on the premise of reusable pieces of software that encapsulate logic and data. If you've done or read about Object-Orientated Programming (OOP) then you should be fairly familiar with the concept of components, as both concepts share common design features (e.g. reusability, encapsulation). While it was possible to create JavaScript components since the early years of the language -- via its OOP facilities [5] -- the practice never really took off until a series of JavaScript frameworks made the use of components easy and commonplace.

The main benefit of JavaScript components is they allow HTML and JavaScript to be rolled into the same unit and not live separately, unlike the process illustrated in the previous jQuery example in listing 1-2. With JavaScript components it also becomes possible to re-use the same unit multiple times in the same application or across projects. In addition, JavaScript components also offer the possibility to create parent-child relationships between components so actions and data are shared. And finally, with JavaScript components it becomes easier to test UI behavior, since presentation and logic are encapsulated into the same unit.

Though the purpose of JavaScript components is clear, implementation wise JavaScript components vary -- sometimes widely -- depending on the underlying library or framework where they come from. Much like the selection of other web technologies, JavaScript components require you invest time learning subtleties that only work in the context of certain libraries or JavaScript frameworks. The most popular JavaScript component approaches -- of which I'll go into greater detail later -- include:

JavaScript MVC

With the surge of AJAX, many designers realized it was possible to deliver a single web page and simulate the functionality of dozens of web pages via AJAX, giving the end user a cleaner experience rather than him jumping from web page to web page. This paved the way for Single Page Applications or as their also known by their acronym: SPA.

Like other demands before it, SPA really pushed the boundaries of what was possible with JavaScript and web applications. Let's start this discussion from the previous jQuery example in listing 1-2 which is a 'toy' web page that uses a couple of JavaScript event handlers. Now envision a real-life web page to display a product catalog, if a 'toy' web page has a couple of JavaScript actions, a web page reflecting a real-life process can conservatively have dozens or more JavaScript actions. Managing this amount of JavaScript actions is pretty doable with jQuery, even though you're likely to feel some of the design strains I already mentioned (e.g. difficulty debugging, managing error handling).

But let's not forget you're now doing a SPA. That single product catalog web page with a dozen JavaScript actions will now be lumped together with a sales web page that also has a dozen or more JavaScript related actions, as well as a checkout web page with a dozen or more JavaScript related actions and many more pages like that. At the end, you're likely to have the scenario I forewarned when I talked about jQuery's limitations: hundreds of elements & actions all lumped together in a single page.

So how can you realistically manage hundreds of elements & actions all lumped together in a single HTML page with JavaScript ? Easy, you organize everything with a tried and proven approach. As it turns out, since the dawn of the Internet, web sites had relied on server side stacks in languages like PHP, Java & Python, to design software with interconnected parts that favor maintenance & reusability.

These design patterns consisting of things like web page routing (i.e. what page sequence to follow for a given task), business logic execution and data validation, are known by the broader name Model-View-Controller (MVC) architecture[6].

So faced with the complexities of SPA, JavaScript went ahead and adopted functionalities -- such as routing and dependency injection -- that were once reserved for server-side languages like PHP, Java & Python. And just like that, JavaScript libraries soon became full-fledged JavaScript frameworks that were able to deal with MVC architecture entirely on the browser.

The most popular JavaScript MVC frameworks -- of which I'll go into greater detail later -- include:

JavaScript outside of a browser

Of all the potential JavaScript novelties, the one that can be the most surprising for web development in general is running JavaScript outside of a browser. Even if you don't agree with the idea of JavaScript components or JavaScript MVC, you can't deny both are still bound to the browser where JavaScript has always lived and dominated.

So why would anyone want to run JavaScript outside of a browser with so many solid language choices like PHP, Java and Python ? It turns out someone encountered an unresponsive UI while uploading a file and ended up using JavaScript outside of a browser to get real-time updates [7]. Several years after this experiment, JavaScript code running outside of a browser is now commonplace.

JavaScript code running outside of a browser is dominated by Node JS, which uses the same JavaScript V8 engine[8] used by Google's Chrome browser. What's interesting about Node JS isn't its ability to run JavaScript per se, but rather taking the native asynchronous & non-blocking behavior in JavaScript engines and building on it to facilitate things like real-time web development (e.g. chats, live event publishing) outside browsers.

I can't emphasize enough how Node JS is many things. Node JS operates with a JavaScript engine, so it can execute non-UI JavaScript applications, leveraging JavaScript's event loop design making it ideal for time sensitive & high performance web applications. Node JS also has its own JavaScript APIs for things like HTTP operations, processing buffers, interacting with files and DNS queries, among other things, this means it's like a framework. And in addition, Node JS also comes with a package manager called Npm, which means a lot of modules/libraries/frameworks are available for Node JS via npm.

It's also important to note Node JS doesn't preclude using any of the JavaScript topics I already mentioned, in fact, Node JS actually complements them. For example, you can use both a JavaScript MVC framework like Angular and React JavaScript components -- or one individually -- with Node JS. However, be aware Node JS supports thousands of other JavaScript packages which can be confusing at first. For example, you'll find Node JS packages like Sails and Express that are also JavaScript MVC frameworks, just be aware these last packages are JavaScript MVC server side frameworks, not to be confused with JavaScript MVC client side frameworks like Angular or Ember. So it's possible to end up using many frameworks in the same web application (e.g. React for JavaScript components, Angular for JavaScript MVC on the client and Express for JavaScript MVC on the server, among others)

I advise you to take your time learning about Node JS and JavaScript development outside of a browser, due to its wide scope and amount of options. It should be worth the effort, since practically all modern JavaScript development requires you to navigate the Node JS ecosystem.

Toward the end of 2018, the same person who pioneered Node JS armed with the hindsight of what would make a better Node JS set out to develop Deno. Deno represents an evolutionary step for running JavaScript outside of a browser, since it incorporates many lessons learned over the development of Node JS, including better security and built-in support for TypeScript -- a high-level programming language designed to make JavaScript development easier -- which is described next.

Languages that produce JavaScript: JSX and Typescript

Did you know the JavaScript language was put together in 10 days[9] ? That's not a typo, it was ten days! Can you imagine trying to create a solid software application in 10 days, let alone create a programming language in the same time frame ? The reality is JavaScript at inception was never conceived for such a wide range of purposes like it's used today.

JavaScript's syntax and functionality shortcomings are pretty glaring compared to other programming languages, how bad ? Pretty bad, as in 'break the Internet' bad. This is a true story about how JavaScript broke the Internet [10] which is why I find it so interesting. Let's do a quick exercise to show why and how this happened with JavaScript.

How do you left-pad a string in your favorite programming language ? In Java you can use the language's String.format method, in Python you can use the language's str.rjust method, in PHP you can use the language's str_pad method, but how about JavaScript code ? Well, you won't find a built-in method for this, you would need to use JavaScript's String object and create your own implementation -- like this simple left-pad method. And this is the crux of the problem with JavaScript, for something as simple as left-padding a string -- a feature that's covered out-of-the-box by most programming languages -- you have to write your own implementation.

In this true story, it took a couple of lawyers alleging copyright claims on an apparent innocuous name, to force a developer to unpublish a JavaScript library that offered a left-pad method. As it turns out, this simple JavaScript library with the functionality to left-pad strings was used by thousands of other JavaScript projects, which in turn broke thousands of Internet sites that relied on it. All legal issues and availability assumptions aside, this really shows the functionality holes in JavaScript. You can blame the lawyers all you want, but it's more telling that thousands depended on a third-party JavaScript library for functionality that's standard in most programming languages.

To alleviate some of these shortcomings and in the face of more demanding JavaScript functionalities required by JavaScript components, JavaScript MVC frameworks and JavaScript applications required to run outside of a browser, various initiatives emerged to supplement JavaScript and make the language more flexible and powerful. Among the most important initiatives are:

So what is modern JavaScript ?

After this walkthrough of JavaScript's facets throughout the years, you might be left puzzled pondering "What is modern anyways ?" Well in 1995 modern was JavaScript events, in 2004 modern was AJAX, in 2006 modern was jQuery, in 2010 modern was Angular 1, in 2012 modern was Node JS, in 2014 modern was React, in 2016 modern was Angular 2 and in 2019 modern was the Deno runtime. But don't be fooled, even Angular 2 from 2016 has some traces of the earliest JavaScript events from 1995, just as React from 2014 has some influence from AJAX created 10 years earlier.

So modern JavaScript is really a wide and moving target. You may have learned JavaScript five years ago and some of those techniques may be considered old by today's standards, just as you may know JavaScript techniques from 20+ years ago that are still considered modern best practices. My intent is to take you on a guide through JavaScript's various ins and outs to learn modern JavaScript as it's known today.

  1. https://en.wikipedia.org/wiki/JavaScript#History    

  2. http://dynamicdrive.com/    

  3. https://en.wikipedia.org/wiki/Browser_wars    

  4. https://css-tricks.com/dom/    

  5. https://web.archive.org/web/20150402193611/http://callmenick.com/post/javascript-objects-building-javascript-component-part-1    

  6. https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller    

  7. https://en.wikipedia.org/wiki/Node.js#History    

  8. https://v8.dev/    

  9. https://en.wikipedia.org/wiki/JavaScript#History    

  10. http://arstechnica.com/information-technology/2016/03/rage-quit-coder-unpublished-17-lines-of-javascript-and-broke-the-internet/