Introduction to JavaScript
Learn the basics of JavaScript, including its features, working mechanism, and role in creating dynamic, interactive web applications.
What is JavaScript?
JavaScript is a high level, single threaded programming language which is used for creating interactive web, mobile and desktop apps. It is used to create client as well as server side applications.
The language is standardized by ECMA International under the ECMAScript specification.
Why use JavaScript?
JavaScript provides interactivity to the application. Without JavaScript web apps would be only static applications, ie. display-only apps. All interactivity is provided through JavaScript.
Ex. form validation, show/hide content dynamically, api calls, etc. are done by JavaScript.
JavaScript is not limited to web apps only, it can be used on the server using Node.js, mobile apps using React Native, desktop apps using Electron.
Popular libraries like React, Angular and React Native are built on top of JavaScript, so learning JavaScript opens doors to all these different domains of application.
Full stack capability. It can run on the client as well as on the server.
JavaScript is a popular and mature programming language and has millions of packages created by the community. At least for most cases one will find a package. This makes app development faster, and for common problems we do not need to invent the wheel again.
A few examples
- Form validation — in forms the validation, api call, handling the api response, and updating the UI based on that response is all done by JavaScript.
- Google search suggestions — detects what you’re typing, sends requests in the background, updates suggestions without reloading the page.
- YouTube video player — play/pause, auto-play next video, adjust volume and speed. JavaScript controls the entire video player experience.
The form below is the first of those, running for real on this page. Validation on name and phone: neither can be empty, the name must be 30 characters or fewer, and the phone must be four digits.
Try it
Name is required and must be 30 characters or fewer. Phone must be exactly four digits. Nothing is sent anywhere — the checks run in your browser.
How JavaScript is executed
The browser includes a JavaScript runtime, which is a collection of different parts (or we can say programs) using which our JavaScript code is executed. The JavaScript runtime contains the JavaScript engine, web APIs, queues, etc.
The JavaScript engine
The JavaScript engine is simply a computer program that interprets JavaScript code and executes it. It is responsible for converting human readable JavaScript code into machine readable binary (0 and 1) so the computer hardware can execute it.
The JavaScript engine consists of:
- Parser — converts JS code into an Abstract Syntax Tree (AST)
- Compiler — converts the AST into bytecode. Note, this bytecode is not binary
- Interpreter — executes the bytecode instructions one after another
- Just-in-time compiler — detects frequently executing code and creates its binary, for optimization purposes
When JavaScript code is passed to the JS runtime the code is first parsed by the parser, ie. it is converted to an AST. The AST is passed to the compiler which converts it into bytecode, and that bytecode is passed to the interpreter which executes the instructions one after another.
Optimization: the JIT compiler detects a piece of code which is executing multiple times, marks it as HOT code, and generates a binary of it. So when this code comes up for parsing again, the JS engine knows it is HOT and that machine code already exists for it, and instead of interpreting it directly executes the binary.
So the process is: parsing (converting JS into an AST), compiling (converting the AST to bytecode), interpreting (reading and executing the bytecode instructions one by one), and optimization using the JIT compiler.
In the above flow nowhere are we converting the JS code into binary, so how is JS code getting executed?
Before answering that we should answer two more questions — how is the parser able to convert JS code into an AST, and how is the compiler able to convert an AST into bytecode?
The answer is that they are made in such a way that they understand all the rules of their input, ie. JS code for the parser and an AST for the compiler, and therefore they can convert JS into an AST and an AST into bytecode respectively. Similarly the interpreter knows all the rules of the language and what a particular instruction of bytecode means, and so it can execute it. This is how JavaScript code gets executed.
Note, the parser, compiler, interpreter and JIT compiler are themselves already binary code running on the computer hardware, able to understand their input and process it into the desired output.
Compiled and interpreted languages
To execute any code it must be converted into binary format, because the computer understands binary.
To convert it we have two ways, ie. compilation and interpretation.
Compilation: the process in which the entire source code is translated into machine code (executable format) before execution at build time, so it can be run directly by the system.
Interpretation: the process in which code is translated and executed at runtime, where instructions are processed step by step by an interpreter.
JavaScript is neither purely compiled nor purely interpreted. JavaScript uses an interpreter which executes code line by line, which makes it an interpreted language, but it also uses a JIT compiler which compiles frequently required code into machine code, and for that piece of code no interpretation is required — in that case JavaScript becomes a compiled language. Therefore JavaScript uses both compilation and interpretation for better performance.
The single threaded nature of JavaScript
JavaScript is a single threaded language, which means it has only one call stack, can only do one thing at a time, and executes code sequentially.
This means if a function takes too long to execute it blocks other code, making the app inaccessible and slow. But JavaScript apps feel fast. The reason is that the environment JavaScript runs in is not only the JavaScript engine — it consists of the engine, timers, api calls, events, queues, and so on. This is possible because of the web APIs, callback queues and the event loop.
JavaScript is single threaded, but its runtime environment allows it to handle asynchronous operations efficiently without blocking the main thread. Even though it is single threaded it can handle asynchronous operations through the event loop and browser APIs.