Introduction to JavaScript
What is JavaScript?
JavaScript (JS) is a popular programming language used in a variety of software systems. It is used in server-side web applications, Android and iPhone apps and traditionally in web pages. Still virtually every website uses client-side JavaScript.
A programming language is a formal language or "computer language" used to write instructions for programmable machines such as computers. There are many different programming languages. Each programming language is defined by specific grammatical structure rules (the syntax) and by the processes a computer follows when executing the instructions (the semantics). Each programming language is particularly well suited to a particular purpose, to a particular type of application or to a particular area of application. Each language has its own pros and cons.
JavaScript is particularly useful for programming web based applications. For example in figure 1, a client-side JavaScript is used to add some interactivity to a web page. This JavaScript dynamically manipulates HTML and styling.
<body>
<label>Your name: <input id="inputName" type="text" /></label>
<p id="greeting">Hello <span>You</span>!</p>
<script>
"use strict";
const inputName = document.querySelector('#inputName');
const outputName =document.querySelector('#greeting > span');
inputName.addEventListener('input', function(){
outputName.style.color = "#" + Math.floor(Math.random()*16777215).toString(16);
outputName.textContent = inputName.value;
});
</script>
</body>
Result:
Hello You!
<script>
element) alters the content and styling of an HTML <span>
element,
based on what the user types in the input field. With every key stroke in the input field, the text gets a different random color.
JavaScript is a dynamically typed programming language, often referred to as a scripting language. This means that, as opposed to static programming languages such as Java, in JavaScript it is possible to change the type of a variable (for instance from string to boolean) while the program is running. JavaScript is a prototype-based, object-oriented programming (OOP) language that also supports (simulates) many class-based features. These topics will all be covered in detail later in this tutorial.
Executing a computer program
With a programming language one can write a computer program. A computer program is a set of instructions that can be executed by a computer to provide some intended output. The computer's central processing unit (CPU), that finally executes a program, only 'understands' instructions written in a low level programming language or machine code. To move away from all the technical details of processor instructions and so making programming easier and more understandable for human developers, high-level programming languages, such as JavaScript, were developed.
A computer program written in a high-level programming language first needs to be parsed. Parsing means that the written source code is converted into a data structure, or more specifically a syntax tree. A syntax tree is a representation of the syntactic structure of the code suitable for the compiling process.
Next, the parsed data needs to be compiled to machine code to create an executable program. The final phase in which the machine code is being executed by the processor is called run-time. So, the entire process from programmed source code up to executing the program involves successively parsing, compiling and running (executing) machine code.
JavaScript engines
JavaScript is parsed and compiled by a JavaScript engine, sometimes called a JavaScript Virtual Machine.
The JavaScript engine does not create an explicit binary executable file (.exe
file) that can be executed independently.
A JavaScript engine uses just-in-time compilation,
meaning that compilation happens during execution, rather than before execution.
A JS engine "runs" a program from the plain text JavaScript code, via parsing to just-in-time compilation, which directly executes the machine code.
Every major web browser has a JavaScript engine. It runs the JS of a web application client-side, i.e., on the user's device. JavaScript engines are also embedded in JavaScript runtime environments (frameworks), such as Node.js, to run scripts server-side. Server-side scripts run on a web-server to dynamically compose web pages to be sent to the user's web browser. Also mobile native apps, developed in certain application frameworks, such as in the popular React Native framework, run the JS via an embedded JS-engine.
Notable JavaScript engines and some of their main implementations are:
- V8, implemented in Chromium-based browsers (Google Chrome, Microsoft Edge) and in framework Node.js
- SpiderMonkey, implemented in Gecko-based browsers (Mozilla Firefox)
- JavaScriptCore, implemented in WebKit-based browsers (Apple Safari) and in iOS (iPhone) apps using the React Native framework
- Hermes, a lightweight JS-engine optimized for Android apps using the React Native framework
ECMAScript
ECMAScript is the specification that JavaScript is based on. ECMAScript is standardized by Ecma International. So ECMAScript (ES) is a script-language specification and JavaScript (JS) is a programming language following this specification. ECMAScript, first released in 1997, extends its specification each edition with new features. A specific ECMAScript version is denoted with the year of publication or the edition number: ECMAScript 2020 or ES2020 or ES11 for edition 11 published in June 2020.
Strict mode
JavaScript can be declared to be executed in a restricted variant of JavaScript. JS-engines will then compile this code in so called strict mode. By default code will execute in non-strict mode, allowing syntax to be "less clean" and "more sloppy". JavaScript in non-strict mode is often referred to as "sloppy mode", "normal code" or "normal JavaScript" (because it is the default mode).
Strict mode, when invoked, applies to entire scripts (it has global scope) or to individual functions within a JavaScript (it has local scope).
To invoke strict mode, the string "use strict";
must be put at the beginning of the script (or the function's body),
before any other statements.
JavaScript modules and classes execute by default in strict mode, with no statement needed (later more about modules and classes).
function MyFunctionInStrictMode() {
'use strict';
// Here goes some function-level strict mode JS syntax...
}
JavaScript written in strict mode is cleaner and more robust. It makes code better arranged, more accessible, more durable and easier to understand what's going on when problems occur. Syntax mistakes in normal code may be accepted and ignored while in strict mode they result in an error. Code in non-strict mode runs with these silent errors with possible unexpected results. Strict mode also prohibits or fixes syntax that prevents JavaScript engines from doing optimizations and it prohibits some syntax likely to be defined in future versions of ECMAScript.
Older browser versions may not support strict mode. Those browsers not supporting strict mode may run code in strict mode with different behavior from browsers that do support strict mode. Make sure to test your code in browsers that do and don't support strict mode when you want your strict code to be reliable also in older browser versions.
Client-side JavaScript
Although JavaScript can run server-side and can be used to run apps on a (mobile) device, running it client-side, in-browser, is probably the easiest and safest way to set up a JavaScript application. Client-side JavaScript can add or modify HTML, content and styles of a web page, it can interact with user's actions, it can communicate with the server and locally store data, for instance in cookies. Interactions with files, programs, hardware (e.g. the camera) or memory outside the browser are limited, because of safety reasons.
Adding JS to a web page
Client-side JavaScript runs in a web browser or more generally in a user agent.
The JS code can be embedded in or attached to an HTML document.
We can use the HTML <script>
element to embed JavaScript almost anywhere in an HTML document.
Since JS often interacts with HTML and CSS it should be placed after the HTML it interacts with.
JS cannot interact with HTML that comes after the script and has not been processed yet.
Common practice is to place the <script>
element(s) at the end of the body, just before the </body>
closing tag.
An alternative strategy is to attach the script to a
DOMContentLoaded
event
that executes the script after the HTML document has been completely loaded and parsed (without waiting for stylesheets).
The script can then be placed anywhere in the HTML document.
Also external script, in a separate file (.js file extension), can be attached to a web document, using the same <script>
element.
This is done by a src
attribute. A <script>
element with an src
attribute
ignores content within the <script>
element, if any exists.
External script files are generally used for scripts used on multiple pages.
In case of a <script>
element with a src
attribute present, the
attributes
defer
and async
are available to control when the script should be executed with respect to the loading and parsing of the rest of the HTML document.
<!doctype html>
<html>
<head>
<title>My Web Page</title>
<script defer src="script.js">attaches an external JS file</script>
<script>
window.addEventListener('DOMContentLoaded', function(event) {
console.log('DOM fully loaded and parsed');
});
</script>
</head>
<body>
<h1>My First Web Page</h1>
<script>
console.log("This is some embedded JavaScript at the end of the document")
</script>
</body>
</html>
Also note that the scripts in multiple <script>
elements in a document are aware of each other's code.
For instance, a (global) constant declared in one script cannot be redeclared in a next script. Or a script using jQuery functions will
throw an error when this
script executes before the external jQuery JavaScript file has been loaded.
JavaScript libraries and web frameworks
As previously mentioned, an external .js
file can be attached to a web page.
These files can be provided from the same domain as the page, but they can also be third-party JavaScripts
distributed through a Content Delivery Network (CDN).
Such third-party JavaScripts are called JavaScript libraries.
In the next example the popular
jQuery library is attached through the
Google CDN.
<head>
<title>My Web Page</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
A JavaScript library contains pre-written JavaScript code that allows for easier development of applications. Often needed and common functions that are not part of native JavaScript can be included, allowing for developers to concentrate more on programming the specifics of the application. There are many libraries for many application purposes. There are libraries aimed to aid in the creation of graphical user interfaces or in the creation of graphics or in the manipulation of the DOM etc. See this non-complete List of JavaScript libraries.
Although libraries are meant to make programming easier, they often require some studying to get acquainted with the library's specifics. Some of the libraries (e.g. jQuery) even make code look like it's a different programming language, distinct from native JavaScript. Libraries do not necessarily make programming easier for every application. Furthermore, using a library also requires the downloading of the library script file(s), which affects loading performance in a negative way. Nevertheless, the use of libraries and frameworks is very popular in client-side scripting. The vast majority of websites uses at least one library or framework. The term "vanilla JavaScript" has been coined for "native" JavaScript, without the use of any library or framework. This tutorial focuses on "vanilla JavaScript"; libraries and frameworks are not involved.
Next the JavaScript from figure 1 and the alternative script in jQuery:
// code in native JavaScript:
const inputName = document.querySelector('#inputName');
const outputName =document.querySelector('#greeting > span');
inputName.addEventListener('input', function(){
outputName.style.color = "#" + Math.floor(Math.random()*16777215).toString(16);
outputName.textContent = inputName.value;
});
// code in jQuery:
$(document).ready(function(){
const inputName = $("#inputName");
const outputName = $("#greeting > span");
inputName.on("input", function(){
outputName.css("color","#" + Math.floor(Math.random()*16777215).toString(16));
outputName.text(inputName.val());
});
});
So, there are libraries and frameworks. The terms are often used interchangeably, but they are not entirely the same things.
Both provide third-party pre-written JavaScript code that allows for easier development of applications.
A library provides functions that the programmer can pick and use where the programmer wants them to use in the code.
A framework provides a template; the architecture of the code the programmer has to follow and only fill in the blanks as desired.
With both a framework and a library the third-party JS needs to be included in the web page by means of the <script>
element with
src
attribute. Popular front-end web frameworks are
AngularJS and
Vue.js.
Transpiling and polyfilling
Traditionally a compiler translates from a higher level programming language to a lower level programming language, typically to machine code. With source-to-source compiling (also called transpiling or transcompiling) a compiler converts (translates) between source code in different programming languages that are (approximately) at the same level. For example to convert legacy code to a newer language.
Transpiling to JavaScript is available for a number of popular and modern programming languages like Dart (via the dart2js compiler) and Kotlin (Kotlin/JS). There are even script languages that always transpile to JavaScript, before running. They are designed in an effort to improve brevity, readability and availability of specific features, over JavaScript. Examples are CoffeeScript and TypeScript.
Brython is a project to make it possible to
type Python code directly within a <script>
element in the HTML. The Brython JS library transcompiles the code to JavaScript.
Python is a popular, clear and easy to learn programming language. See this Brython example
that does something similar to
what the JavaScript in figure 1 does.
JavaScript to JavaScript transpilers are often used to compile JS code in which some of the latest specified syntax constructs are used, into JS code in which those new syntax constructs are rewritten using older syntax constructs. This ensures that JavaScript engines that do not yet support the new syntax will still run the code as intended. Babel and Google Traceur are examples of prominent JS to JS transpilers.
New versions of JavaScript may also introduce new built-in methods (functions). User's JavaScript engines may not yet "know about" these new methods. To ensure an error-free running of the code in all (most) browsers, the developer can include the missing methods in the code. This is called polyfilling. Polyfills for many functions are available. Some providers are ES6 Shim, core-js and Polyfill.io.
JavaScript build tools
The simplest application to write code in is a simple text editor. There are text editors specifically designed to write computer code, called (source) code editors. They typically have features like line numbering, syntax highlighting, auto-completion, etc. A free and basic code editor for Windows is Notepad++.
An IDE (Integrated Development Environment) is a more sophisticated development tool that typically integrates a code editor, file manager, debugger, compiler and often also features like automated testing, a version control system (Git/CVS) and automated transpiling.
Free and popular IDEs are (among others) Visual Studio Code and Eclipse. Paid and popular IDEs are (among others) Visual Studio and WebStorm. All are well-suited for working on JavaScript projects.
A task runner bundles build automation tools. They are used to automatically perform frequent tasks such as minification (compressing JS-files), testing and automated transpiling (e.g. via a Babel plugin). Task runners are often integrated in an IDE. Task runners for JavaScript are (among others) Grunt, gulp.js and webpack.
For trying out code that is discussed in this tutorial a basic code editor (e.g. Notepad++) is sufficient. How to use more advanced JavaScript build tools is not part of this tutorial. They are briefly explained here in this section just to give some front-end development context to programming in JavaScript.
In-browser debugging
Debugging is the process of finding and resolving "bugs" (errors) within the code. IDEs typically contain advanced debugging tools, but also browsers provide debugging functions.
Browsers Google Chrome and Mozilla Firefox both provide pretty good "web developers tools". Part of the web developers tools is the console. An error that occurs while running the JavaScript, terminates execution and logs a message to the console. The error message generally contains what kind of error, a short explanation and a line number which indicates where in the code the error emerged.
You can also add a console log function (method) anywhere in your code which outputs a particular message to the console
at a particular moment during execution.
The statement console.log("Hello world!");
outputs the message "Hello world!" to the console.
Logging values at certain positions in the code is an often used method in debugging.
It enables the developer to trace and examine what happens during the execution of the code.
The console
object provides many more specific logging methods than the general logging method console.log()
and
provides syntaxes to dynamically compose messages and different ways to present and style the messages.
See this
MDN web doc on the console
object
for more information.
You can open the web developers tools via the browser's menu, or by pressing the F12-key or Ctrl+Shift+I (Windows) or Command ⌘+Option ⌥+I (Mac) on the keyboard. The tab "console" opens the console. In all other tabs you can open the console at the bottom by pressing ESC.
You can also type JavaScript directly into the console's command line, at the bottom of the console. After pressing Shift+↵ Enter you can insert a next line, if desired. Pressing ↵ Enter will run the JavaScript.
The web developers tools also provides a "Debugger" (in Chrome called "Sources") tab.
The debugger tab has 3 panes. From left to right; a source list pane (list of the files with code loaded into the page),
a source pane (shows the actual code of the selected source file) and a pane with options
to pause the execution (breakpoints), to trace the execution and to examine the code state at every pause.
JavaScript also provides a debugger
statement
to invoke debugging functionality of the Debugger where the statement is inserted in your code, when the Debugger is active.
You can learn more about how to use the in-browser web developers tools, or more specifically the in-browser debugger, through the following links: