In this article, my goal is to offer an easily understandable technical overview of the JavaScript language, tailored for entry-level developers. I will cover a range of general technical aspects of JavaScript, providing insights into its key concepts and features. Additionally, I will include plenty of helpful resources for readers to delve deeper into the language without the hassle of searching extensively for reliable articles.
TLDR;
JavaScript is a high-level, dynamic, single-threaded language which is stack-oriented and JIT compiled.
Abbreviated as JS, it was created in 1995 to introduce interactivity to static web pages.
JavaScript adheres to the ECMAScript standard, specified in the standard ECMA-262.
JavaScript consists of two types of constructs: Primitives and Non-Primitives.
JavaScript is always pass-by-value language and treats functions as first-class citizens.
The utility of JavaScript's Primitives can be extended through Primitive Wrappers. This is achieved by invoking a Constructor function with the primitive as its argument.
The high level intro
JavaScript has been a foundational technology since the introduction of the World Wide Web. It was created by Brendan Eich in 1995. Over the years, JS has evolved significantly, transforming from a language that made static HTML content interactive to a powerful cornerstone of modern-day web applications.
To appeal to developers at that time, JavaScript drew inspiration from languages like C and Lisp. Apart from being a high-level, single-threaded language it is Just-In-Time compiled (JIT) and dynamically typed.
The specification
JavaScript conforms to a set of specification created and maintained by an organisation called European Computer Manufacturers Association, ECMA. Apart from creating computer language specifications, ECMA is involved in standardising various areas, such as multimedia communications and electronic equipment safety. Each specification they produce is assigned a reference number or a code.
The specification code followed by JavaScript is ECMA-262. It defines a general-purpose, vendor-neutral scripting language called ECMAScript. You can find the latest draft of the standard here. In essence, ECMAScript serves as the blueprint for JavaScript.
So, if someone mentions that ECMAScript is the same as JavaScript, correct them:
ECMAScript refers to the standard described in the ECMA-262 specification. JavaScript is a language that conforms to this standard, with some variations, which we will discuss below.
For more detailed information on the relationship between ECMAScript and JavaScript evolution, you can read this article.
Before discussing the variations, let's mention an important group called TC39, which is part of ECMA.
TC39 is a group of developers and academics which is responsible for understanding the specification and evolving JavaScript, conforming to the sepcification. If you had trouble with different versions of JavaScript like ES6, ES5, ES3 etc, you now know who to blame.
Regarding variations from the specification, JavaScript incorporates a handful of features not mentioned in ECMA-262 (like ArrayBuffers). These intricate details further differentiate ECMAScript from JavaScript.
That covers the general overview about specifications. Now, let's delve into some implementation details of the language.
JavaScript General Characteristics
Before starting development with JavaScript, it's essential to understand its general characteristics.
Primitives, Non-Primitives and Primitive Wrappers
In JavaScript, everything is categorised as either a Primitive type or a Non-Primitive type (i.e. Objects).
- Primitives are immutable and single valued.
- Non-Primitives, on the other hand, are objects.
There are seven primitive types in the language:
number
bigInt
string
boolean
null
undefined
-
Symbol
On the other hand, constructs like functions and arrays are a special type of object and hence are classified as Non-Primitves. It is safe to assume that any language construct that is not a Primitive is classified as an object.
Constructors and Primitive Wrappers
While working with JavaScript, you might come across built-in constructor functions that resemble the names of Primitives. These are: String()
, Number()
and Boolean()
.
const aString = 'What am I?'
const aStringObject = new String(aString);
console.log(typeof aString); //string
console.log(typeof aStringObject); //object
The motivation behind having a constructor function for primitive values is to extend the functionality of a primitive. Primitives are single immutable values, while non-primitives are objects, so they can have different attributes and functions assigned to them. This feature allows us to add utility to a primitive, essentially extending its ability.
In the example above, when we use a constructor function on a primitive, it enables us to use certain methods on the value defined in the String
object. The constructor function (String()
) wraps the primitive into a String
object, becoming a Primitive Wrapper. This object contains functions like toUpperCase()
, toLowerCase()
, charAt()
, etc., which can now be used on the wrapped primitive value directly.
aStringObject.toUpperCase(); // WHAT AM I?
Meanwhile, you may also notice that we can use methods available in the String
object on a primitive value without explicitly wrapping it in a Constructor, as shown below:
aString.toLowerCase() // what am i?
This is because JavaScript implicitly wraps the String
object whenever it notices that we are trying to access one of the functions present in the Wrapper. This process of automatic implicit type conversion is called Coercion. You can explore more about it here
Function as first class citizen
The concept of first-class and second-class citizens originated with Algol.
Although not strictly defined at that time, a first-class citizen is generally something that supports all types of available operations on itself. This includes being passed as arguments, returned from a function, and assigned to a variable.
In JavaScript function behave as first-class citizens because all the functions are a variation of JavaScript objects, which as we have studied are building blocks of the language along with Primitives. Learn more about first-class functions here
The Runtime Environment Overview
When we execute JavaScript code, it goes through a runtime process involving several entities. To understand the end-to-end execution process, we'll take a top-down approach to break it down step-by-step. This means we start from a file with .js extension containing some JavaScript code.
The JavaScript code is executed as follows, steps ordered chronologically:
- Identifying the source code The runtime identifies the source code in the .js file. For simplicity, we assume there are no syntactical errors in the source code.
- Tokenization (Lexing) The source code is tokenized, a process known as tokenization or lexing. This breaks the code into smaller units called tokens.
- Abstract Syntax Tree Generation The tokenized code is used to generate the Abstract Syntax Tree (AST) which represents the structure of the code. This process is called as parsing.
- Code Generation The generated AST is used to create executables, sometimes referred to as byte-code. This step is known as code generation.
This is just a high level explanation of the JavaScript code lifecycle. For in-depth exploration, checkout this article, after you have read the overview. It will take you to the abyss.
Finally, the byte-code is translated into machine code, with platform-dependent optimisations, and executed to produce the required results.
The following picture summarises the process:
Conclusion
In this article, I have covered essential topics that provide a strong technical foundation for those who are new to learning the JavaScript language. If you're starting to learn JavaScript, these topics will give you a better perspective on the language.
For more insights into JavaScript technicalities, I highly recommend checking out this resource beautifully summarised by Tony Stubblebine which served as my inspiration for writing this article. I've made sure that the content of both articles is unique to offer the readers the most value.
Thank you for taking the time to read my article! I would greatly appreciate your suggestions and feedback in the comments below, as it will help me further improve the content for the readers.
Happy Coding!
Top comments (0)