Recent from talks
Contribute something
Nothing was collected or created yet.
JavaScript
View on Wikipedia
| JavaScript | |
|---|---|
Screenshot of JavaScript source code | |
| Paradigms | Multi-paradigm: event-driven, functional, imperative, procedural, object-oriented |
| Family | ECMAScript |
| Designed by | Brendan Eich of Netscape first; then others contributed to ECMAScript standard |
| First appeared | 4 December 1995[1] |
| Stable release | ECMAScript 2024[2] |
| Preview release | ECMAScript 2025[3] |
| Typing discipline | Dynamic, weak, duck |
| Memory management | Garbage collected |
| Scope | lexical |
| Filename extensions | .js • .mjs • .cjs[4] |
| Website | ecma-international |
| Major implementations | |
| V8, JavaScriptCore, SpiderMonkey; Chakra (deprecated) | |
| Influenced by | |
| Java,[5][6] Scheme,[6] Self,[7] AWK,[8] HyperTalk[9] | |
| Influenced | |
| ActionScript, ArkTS, AssemblyScript, CoffeeScript, Dart, Haxe, JS++, Opa, TypeScript | |
| |
JavaScript (JS)[a] is a programming language and core technology of the Web, alongside HTML and CSS. It was created by Brendan Eich in 1995.[6] Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.[10]
Web browsers have a dedicated JavaScript engine that executes the client code. These engines are also utilized in some servers and a variety of apps. The most popular runtime system for non-browser usage is Node.js.[11]
JavaScript is a high-level, often just-in-time–compiled language that conforms to the ECMAScript standard.[12] It has dynamic typing, prototype-based object-orientation, and first-class functions. It is multi-paradigm, supporting event-driven, functional, and imperative programming styles. It has application programming interfaces (APIs) for working with text, dates, regular expressions, standard data structures, and the Document Object Model (DOM).
The ECMAScript standard does not include any input/output (I/O), such as networking, storage, or graphics facilities. In practice, the web browser or other runtime system provides JavaScript APIs for I/O.
Although Java and JavaScript are similar in name and syntax, the two languages are distinct and differ greatly in design.
History
[edit]Creation at Netscape
[edit]The first popular web browser with a graphical user interface, Mosaic, was released in 1993. The lead developers of Mosaic then founded the Netscape corporation, which released a more polished browser, Netscape Navigator, in 1994. This quickly became the most-used.[13]
During these formative years of the Web, web pages could only be static, lacking the capability for dynamic behavior after the page was loaded in the browser. There was a desire in the flourishing web development scene to remove this limitation, so in 1995, Netscape decided to add a programming language to Navigator. They pursued two routes to achieve this: collaborating with Sun Microsystems to embed the Java language, while also hiring Brendan Eich to embed the Scheme language.[6]
The goal was a "language for the masses",[14] "to help nonprogrammers create dynamic, interactive Web sites".[15] Netscape management soon decided that the best option was for Eich to devise a new language, with syntax similar to Java and less like Scheme or other extant scripting languages.[5][6] Although the new language and its interpreter implementation were called LiveScript when first shipped as part of a Navigator beta in September 1995, the name was changed to JavaScript for the official release in December.[6][1][16][17]
The choice of the JavaScript name has caused confusion, implying that it is directly related to Java. At the time, the dot-com boom had begun and Java was a popular new language, so Eich considered the JavaScript name a marketing ploy by Netscape.[14]
Adoption by Microsoft
[edit]Microsoft debuted Internet Explorer in 1995, leading to a browser war with Netscape. On the JavaScript front, Microsoft created its own interpreter called JScript.[18]
Microsoft first released JScript in 1996, alongside initial support for CSS and extensions to HTML. Each of these implementations was noticeably different from their counterparts in Netscape Navigator.[19][20] These differences made it difficult for developers to make their websites work well in both browsers, leading to widespread use of "best viewed in Netscape" and "best viewed in Internet Explorer" logos for several years.[19][21]
The rise of JScript
[edit]Brendan Eich later said of this period: "It's still kind of a sidekick language. It's considered slow or annoying. People do pop-ups or those scrolling messages in the old status bar at the bottom of your old browser."[14]
In November 1996, Netscape submitted JavaScript to Ecma International, as the starting point for a standard specification that all browser vendors could conform to. This led to the official release of the first ECMAScript language specification in June 1997.
The standards process continued for a few years, with the release of ECMAScript 2 in June 1998 and ECMAScript 3 in December 1999. Work on ECMAScript 4 began in 2000.[18]
However, the effort to fully standardize the language was undermined by Microsoft gaining an increasingly dominant position in the browser market. By the early 2000s, Internet Explorer's market share reached 95%.[22] This meant that JScript became the de facto standard for client-side scripting on the Web.
Microsoft initially participated in the standards process and implemented some proposals in its JScript language, but eventually it stopped collaborating on ECMA work. Thus ECMAScript 4 was mothballed.
Growth and standardization
[edit]During the period of Internet Explorer dominance in the early 2000s, client-side scripting was stagnant. This started to change in 2004, when the successor of Netscape, Mozilla, released the Firefox browser. Firefox was well received by many, taking significant market share from Internet Explorer.[23]
In 2005, Mozilla joined ECMA International, and work started on the ECMAScript for XML (E4X) standard. This led to Mozilla working jointly with Macromedia (later acquired by Adobe Systems), who were implementing E4X in their ActionScript 3 language, which was based on an ECMAScript 4 draft. The goal became standardizing ActionScript 3 as the new ECMAScript 4. To this end, Adobe Systems released the Tamarin implementation as an open source project. However, Tamarin and ActionScript 3 were too different from established client-side scripting, and without cooperation from Microsoft, ECMAScript 4 never reached fruition.
Meanwhile, very important developments were occurring in open-source communities not affiliated with ECMA work. In 2005, Jesse James Garrett released a white paper in which he coined the term Ajax and described a set of technologies, of which JavaScript was the backbone, to create web applications where data can be loaded in the background, avoiding the need for full page reloads. This sparked a renaissance period of JavaScript, spearheaded by open-source libraries and the communities that formed around them. Many new libraries were created, including jQuery, Prototype, Dojo Toolkit, and MooTools.
Google debuted its Chrome browser in 2008, with the V8 JavaScript engine that was faster than its competition.[24][25] The key innovation was just-in-time compilation (JIT),[26] so other browser vendors needed to overhaul their engines for JIT.[27]
In July 2008, these disparate parties came together for a conference in Oslo. This led to the eventual agreement in early 2009 to combine all relevant work and drive the language forward. The result was the ECMAScript 5 standard, released in December 2009.
Reaching maturity
[edit]Ambitious work on the language continued for several years, culminating in an extensive collection of additions and refinements being formalized with the publication of ECMAScript 6 in 2015.[28]
The creation of Node.js in 2009 by Ryan Dahl sparked a significant increase in the usage of JavaScript outside of web browsers. Node combines the V8 engine, an event loop, and I/O APIs, thereby providing a stand-alone JavaScript runtime system.[29][30] As of 2018, Node had been used by millions of developers,[31] and npm had the most modules of any package manager in the world.[32]
The ECMAScript draft specification is currently maintained openly on GitHub,[33] and editions are produced via regular annual snapshots.[33] Potential revisions to the language are vetted through a comprehensive proposal process.[34][35] Now, instead of edition numbers, developers check the status of upcoming features individually.[33]
The current JavaScript ecosystem has many libraries and frameworks, established programming practices, and substantial usage of JavaScript outside of web browsers.[17] Plus, with the rise of single-page applications and other JavaScript-heavy websites, several transpilers have been created to aid the development process.[36]
Trademark
[edit]"JavaScript" is a trademark of Oracle Corporation in the United States.[37][38] The trademark was originally issued to Sun Microsystems on 6 May 1997, and was transferred to Oracle when they acquired Sun in 2009.[39][40]
A letter was circulated in September 2024, spearheaded by Ryan Dahl, calling on Oracle to free the JavaScript trademark.[41] Brendan Eich, the original creator of JavaScript, was among the over 14,000 signatories who supported the initiative.
Website client-side usage
[edit]JavaScript is the dominant client-side scripting language of the Web, with 99% of all websites using it for this purpose.[10] Scripts are embedded in or included from HTML documents and interact with the DOM.
All major web browsers have a built-in JavaScript engine that executes the code on the user's device.
Examples of scripted behavior
[edit]- Loading new web page content without reloading the page, via Ajax or a WebSocket. For example, users of social media can send and receive messages without leaving the current page.
- Web page animations, such as fading objects in and out, resizing, and moving them.
- Playing browser games.
- Controlling the playback of streaming media.
- Generating pop-up ads or alert boxes.
- Validating input values of a web form before the data is sent to a web server.
- Logging data about the user's behavior then sending it to a server. The website owner can use this data for analytics, ad tracking, and personalization.
- Redirecting a user to another page.
- Storing and retrieving data on the user's device, via the storage or IndexedDB standards.
Libraries and frameworks
[edit]Over 80% of websites use a third-party JavaScript library or web framework as part of their client-side scripting.[42]
jQuery is by far the most-used.[42] Other notable ones include Angular, Bootstrap, Lodash, Modernizr, React, Underscore, and Vue.[42] Multiple options can be used in conjunction, such as jQuery and Bootstrap.[43]
However, the term "Vanilla JS" was coined for websites not using any libraries or frameworks at all, instead relying entirely on standard JavaScript functionality.[44]
Other usage
[edit]The use of JavaScript has expanded beyond its web browser roots. JavaScript engines are now embedded in a variety of other software systems, both for server-side website deployments and non-browser applications.
Initial attempts at promoting server-side JavaScript usage were Netscape Enterprise Server and Microsoft's Internet Information Services,[45][46] but they were small niches.[47] Server-side usage eventually started to grow in the late 2000s, with the creation of Node.js and other approaches.[47]
Electron, Cordova, React Native, and other application frameworks have been used to create many applications with behavior implemented in JavaScript. Other non-browser applications include Adobe Acrobat support for scripting PDF documents[48] and GNOME Shell extensions written in JavaScript.[49]
Oracle used to provide Nashorn, a JavaScript interpreter, as part of their Java Development Kit (JDK) API library along with jjs a command line interpreter as of JDK version 8. It was removed in JDK 15. As a replacement Oracle offered GraalJS which can also be used with the OpenJDK which allows one to create and reference Java objects in JavaScript code and add runtime scripting in JavaScript to applications written in Java.[50][51][52][53]
JavaScript has been used in some embedded systems, usually by leveraging Node.js.[54][55][56]
Execution
[edit]JavaScript engine
[edit]Runtime system
[edit]A JavaScript engine must be embedded within a runtime system (such as a web browser or a standalone system) to enable scripts to interact with the broader environment. The runtime system includes the necessary APIs for input/output operations, such as networking, storage, and graphics, and provides the ability to import scripts.
JavaScript is a single-threaded language. The runtime processes messages from a queue one at a time, and it calls a function associated with each new message, creating a call stack frame with the function's arguments and local variables. The call stack shrinks and grows based on the function's needs. When the call stack is empty upon function completion, JavaScript proceeds to the next message in the queue. This is called the event loop, described as "run to completion" because each message is fully processed before the next message is considered. However, the language's concurrency model describes the event loop as non-blocking: program I/O is performed using events and callback functions. This means, for example, that JavaScript can process a mouse click while waiting for a database query to return information.[61]
Features
[edit]The following features are common to all conforming ECMAScript implementations unless explicitly specified otherwise. The number of cited reserved words including keywords is 50–60 and varies depending on the implementation.
Imperative and structured
[edit]JavaScript supports much of the structured programming syntax from C (e.g., if statements, while loops, switch statements, do while loops, etc.). One partial exception is scoping: originally JavaScript only had function scoping with var; block scoping was added in ECMAScript 2015 with the keywords let and const. Like C, JavaScript makes a distinction between expressions and statements. One syntactic difference from C is automatic semicolon insertion, which allow semicolons (which terminate statements) to be omitted.[62]
Weakly typed
[edit]JavaScript is weakly typed, which means certain types are implicitly cast depending on the operation used.[63]
- The binary
+operator casts both operands to a string unless both operands are numbers. This is because the addition operator doubles as a concatenation operator - The binary
-operator always casts both operands to a number - Both unary operators (
+,-) always cast the operand to a number. However,+always casts toNumber(binary64) while-preservesBigInt(integer)[64]
Values are cast to strings like the following:[63]
- Strings are left as-is
- Numbers are converted to their string representation
- Arrays have their elements cast to strings after which they are joined by commas (
,) - Other objects are converted to the string
[object Object]whereObjectis the name of the constructor of the object
Values are cast to numbers by casting to strings and then casting the strings to numbers. These processes can be modified by defining toString and valueOf functions on the prototype for string and number casting respectively.
JavaScript has received criticism for the way it implements these conversions as the complexity of the rules can be mistaken for inconsistency.[65][63] For example, when adding a number to a string, the number will be cast to a string before performing concatenation, but when subtracting a number from a string, the string is cast to a number before performing subtraction.
| left operand | operator | right operand | result |
|---|---|---|---|
[] (empty array)
|
+
|
[] (empty array)
|
"" (empty string)
|
[] (empty array)
|
+
|
{} (empty object)
|
"[object Object]" (string)
|
false (boolean)
|
+
|
[] (empty array)
|
"false" (string)
|
"123"(string)
|
+
|
1 (number)
|
"1231" (string)
|
"123" (string)
|
-
|
1 (number)
|
122 (number)
|
"123" (string)
|
-
|
"abc" (string)
|
NaN (number)
|
Often also mentioned is {} + [] resulting in 0 (number). This is misleading: the {} is interpreted as an empty code block instead of an empty object, and the empty array is cast to a number by the remaining unary + operator. If the expression is wrapped in parentheses - ({} + []) – the curly brackets are interpreted as an empty object and the result of the expression is "[object Object]" as expected.[63]
Dynamic
[edit]Typing
[edit]JavaScript is dynamically typed like most other scripting languages. A type is associated with a value rather than an expression. For example, a variable initially bound to a number may be reassigned to a string.[66] JavaScript supports various ways to test the type of objects, including duck typing.[67]
Run-time evaluation
[edit]JavaScript includes an eval function that can execute statements provided as strings at run-time.
Object-orientation (prototype-based)
[edit]Prototypal inheritance in JavaScript is described by Douglas Crockford as:
You make prototype objects, and then ... make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects... Objects inherit from objects. What could be more object oriented than that?[68]
In JavaScript, an object is an associative array, augmented with a prototype (see below); each key provides the name for an object property, and there are two syntactical ways to specify such a name: dot notation (obj.x = 10) and bracket notation (obj["x"] = 10). A property may be added, rebound, or deleted at run-time. Most properties of an object (and any property that belongs to an object's prototype inheritance chain) can be enumerated using a for...in loop.
Prototypes
[edit]JavaScript uses prototypes where many other object-oriented languages use classes for inheritance,[69] but it's still possible to simulate most class-based features with the prototype system.[70] Additionally, ECMAScript version 6 (released June 2015) introduced the keywords class, extends and super, which serve as syntactic sugar to abstract the underlying prototypal inheritance system with a more conventional interface. Constructors are declared by specifying a method named constructor, and all classes are automatically subclasses of the base class Object, similarly to Java.
class Person {
constructor(name) {
this.name = name;
}
}
class Student extends Person {
constructor(name, id) {
super(name);
this.id = id;
}
}
const bob = new Student("Robert", 12345);
console.log(bob.name); // Robert
Though the underlying object mechanism is still based on prototypes, the newer syntax is similar to other object oriented languages. Private variables are declared by prefixing the field name with a number sign (#), and polymorphism is not directly supported, although it can be emulated by manually calling different functions depending on the number and type of arguments provided.[71]
Functions as object constructors
[edit]
Functions double as object constructors, along with their typical role. Prefixing a function call with new will create an instance of a prototype, inheriting properties and methods from the constructor (including properties from the Object prototype).[72] ECMAScript 5 offers the Object.create method, allowing explicit creation of an instance without automatically inheriting from the Object prototype (older environments can assign the prototype to null).[73] The constructor's prototype property determines the object used for the new object's internal prototype. New methods can be added by modifying the prototype of the function used as a constructor.
// This code is completely equivalent to the previous snippet
function Person(name) {
this.name = name;
}
function Student(name, id) {
Person.call(this, name);
this.id = id;
}
var bob = new Student("Robert", 12345);
console.log(bob.name); // Robert
JavaScript's built-in classes, such as Array and Object, also have prototypes that can be modified. However, it's generally considered bad practice to modify built-in objects, because third-party code may use or inherit methods and properties from these objects, and may not expect the prototype to be modified.[74]
Functions as methods
[edit]Unlike in many object-oriented languages, in JavaScript there is no distinction between a function definition and a method definition. Rather, the distinction occurs during function calling. When a function is called as a method of an object, the function's local this keyword is bound to that object for that invocation.
Functional
[edit]JavaScript functions are first-class; a function is considered to be an object.[75] As such, a function may have properties and methods, such as .call() and .bind().[76]
Lexical closure
[edit]A nested function is a function defined within another function. It is created each time the outer function is invoked.
In addition, each nested function forms a lexical closure: the lexical scope of the outer function (including any constant, local variable, or argument value) becomes part of the internal state of each inner function object, even after execution of the outer function concludes.[77]
Anonymous function
[edit]JavaScript also supports anonymous functions.
Delegative
[edit]JavaScript supports implicit and explicit delegation.
Functions as roles (Traits and Mixins)
[edit]JavaScript natively supports various function-based implementations of Role[78] patterns like Traits[79][80] and Mixins.[81] Such a function defines additional behavior by at least one method bound to the this keyword within its function body. A Role then has to be delegated explicitly via call or apply to objects that need to feature additional behavior that is not shared via the prototype chain.
Object composition and inheritance
[edit]Whereas explicit function-based delegation does cover composition in JavaScript, implicit delegation already happens every time the prototype chain is walked in order to, e.g., find a method that might be related to but is not directly owned by an object. Once the method is found it gets called within this object's context. Thus inheritance in JavaScript is covered by a delegation automatism that is bound to the prototype property of constructor functions.
Miscellaneous
[edit]Zero-based numbering
[edit]JavaScript is a zero-index language.
Variadic functions
[edit]An indefinite number of parameters can be passed to a function. The function can access them through formal parameters and also through the local arguments object. Variadic functions can also be created by using the bind method.
Array and object literals
[edit]Like in many scripting languages, arrays and objects (associative arrays in other languages) can each be created with a succinct shortcut syntax. In fact, these literals form the basis of the JSON data format.
Regular expressions
[edit]JavaScript supports regular expressions for text searches and manipulation.[72]: 139
Promises
[edit]A built-in Promise object provides functionality for handling promises and associating handlers with an asynchronous action's eventual result. JavaScript supplies combinator methods, which allow developers to combine multiple JavaScript promises and do operations based on different scenarios. The methods introduced are: Promise.race, Promise.all, Promise.allSettled and Promise.any.
Async/await
[edit]Async/await allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function. Asynchronous, non-blocking code can be written, with minimal overhead, structured similarly to traditional synchronous, blocking code.
Vendor-specific extensions
[edit]Historically, some JavaScript engines supported these non-standard features:
- array comprehensions and generator expressions (like Python)
- concise function expressions (
function(args) expr; this experimental syntax predated arrow functions) - ECMAScript for XML (E4X), an extension that adds native XML support to ECMAScript (unsupported in Firefox since version 21[82])
Syntax
[edit]Variables in JavaScript can be defined using either the var,[83] let[84] or const[85] keywords. Variables defined without keywords will be defined at the global scope.
Arrow functions were first introduced in 6th Edition – ECMAScript 2015. They shorten the syntax for writing functions in JavaScript. Arrow functions are anonymous, so a variable is needed to refer to them in order to invoke them after their creation, unless surrounded by parenthesis and executed immediately.
Here is an example of JavaScript syntax.
// Declares a function-scoped variable named `x`, and implicitly assigns the
// special value `undefined` to it. Variables without value are automatically
// set to undefined.
// var is generally considered bad practice and let and const are usually preferred.
var x;
// Variables can be manually set to `undefined` like so
let x2 = undefined;
// Declares a block-scoped variable named `y`, and implicitly sets it to
// `undefined`. The `let` keyword was introduced in ECMAScript 2015.
let y;
// Declares a block-scoped, un-reassignable variable named `z`, and sets it to
// a string literal. The `const` keyword was also introduced in ECMAScript 2015,
// and must be explicitly assigned to.
// The keyword `const` means constant, hence the variable cannot be reassigned
// as the value is `constant`.
const z = "this value cannot be reassigned!";
// Declares a global-scoped variable and assigns 3. This is generally considered
// bad practice, and will not work if strict mode is on.
t = 3;
// Declares a variable named `myNumber`, and assigns a number literal (the value
// `2`) to it.
let myNumber = 2;
// Reassigns `myNumber`, setting it to a string literal (the value `"foo"`).
// JavaScript is a dynamically-typed language, so this is legal.
myNumber = "foo";
Note the comments in the examples above, all of which were preceded with two forward slashes.
More examples can be found at the Wikibooks page on JavaScript syntax examples.
Security
[edit]JavaScript and the DOM provide the potential for malicious authors to deliver scripts to run on a client computer via the Web. Browser authors minimize this risk using two restrictions. First, scripts run in a sandbox in which they can only perform Web-related actions, not general-purpose programming tasks like creating files. Second, scripts are constrained by the same-origin policy: scripts from one website do not have access to information such as usernames, passwords, or cookies sent to another site. Most JavaScript-related security bugs are breaches of either the same origin policy or the sandbox.
There are subsets of general JavaScript—ADsafe, Secure ECMAScript (SES)—that provide greater levels of security, especially on code created by third parties (such as advertisements).[86][87] Closure Toolkit is another project for safe embedding and isolation of third-party JavaScript and HTML.[88]
Content Security Policy is the main intended method of ensuring that only trusted code is executed on a Web page.
Cross-site scripting
[edit]A common JavaScript-related security problem is cross-site scripting (XSS), a violation of the same-origin policy. XSS vulnerabilities occur when an attacker can cause a target Website, such as an online banking website, to include a malicious script in the webpage presented to a victim. The script in this example can then access the banking application with the privileges of the victim, potentially disclosing secret information or transferring money without the victim's authorization. One important solution to XSS vulnerabilities is HTML sanitization.
Some browsers include partial protection against reflected XSS attacks, in which the attacker provides a URL including malicious script. However, even users of those browsers are vulnerable to other XSS attacks, such as those where the malicious code is stored in a database. Only correct design of Web applications on the server-side can fully prevent XSS.
XSS vulnerabilities can also occur because of implementation mistakes by browser authors.[89]
Cross-site request forgery
[edit]Another cross-site vulnerability is cross-site request forgery (CSRF). In CSRF, code on an attacker's site tricks the victim's browser into taking actions the user did not intend at a target site (like transferring money at a bank). When target sites rely solely on cookies for request authentication, requests originating from code on the attacker's site can carry the same valid login credentials of the initiating user. In general, the solution to CSRF is to require an authentication value in a hidden form field, and not only in the cookies, to authenticate any request that might have lasting effects. Checking the HTTP Referrer header can also help.
"JavaScript hijacking" is a type of CSRF attack in which a <script> tag on an attacker's site exploits a page on the victim's site that returns private information such as JSON or JavaScript. Possible solutions include:
- requiring an authentication token in the POST and GET parameters for any response that returns private information.
Misplaced trust in the client
[edit]Developers of client-server applications must recognize that untrusted clients may be under the control of attackers. The author of an application should not assume that their JavaScript code will run as intended (or at all) because any secret embedded in the code could be extracted by a determined adversary. Some implications are:
- Website authors cannot perfectly conceal how their JavaScript operates because the raw source code must be sent to the client. The code can be obfuscated, but obfuscation can be reverse-engineered.
- JavaScript form validation only provides convenience for users, not security. If a site verifies that the user agreed to its terms of service, or filters invalid characters out of fields that should only contain numbers, it must do so on the server, not only the client.
- Scripts can be selectively disabled, so JavaScript cannot be relied on to prevent operations such as right-clicking on an image to save it.[90]
- It is considered very bad practice to embed sensitive information such as passwords in JavaScript because it can be extracted by an attacker.[91]
- Prototype pollution is a runtime vulnerability in which attackers can overwrite arbitrary properties in an object's prototype.
Misplaced trust in developers
[edit]Package management systems such as npm and Bower are popular with JavaScript developers. Such systems allow a developer to easily manage their program's dependencies upon other developers' program libraries. Developers trust that the maintainers of the libraries will keep them secure and up to date, but that is not always the case. A vulnerability has emerged because of this blind trust. Relied-upon libraries can have new releases that cause bugs or vulnerabilities to appear in all programs that rely upon the libraries. Inversely, a library can go unpatched with known vulnerabilities out in the wild. In a study done looking over a sample of 133,000 websites, researchers found 37% of the websites included a library with at least one known vulnerability.[92] "The median lag between the oldest library version used on each website and the newest available version of that library is 1,177 days in ALEXA, and development of some libraries still in active use ceased years ago."[92] Another possibility is that the maintainer of a library may remove the library entirely. This occurred in March 2016 when Azer Koçulu removed his repository from npm. This caused tens of thousands of programs and websites depending upon his libraries to break.[93][94]
Browser and plugin coding errors
[edit]JavaScript provides an interface to a wide range of browser capabilities, some of which may have flaws such as buffer overflows. These flaws can allow attackers to write scripts that would run any code they wish on the user's system. This code is not by any means limited to another JavaScript application. For example, a buffer overrun exploit can allow an attacker to gain access to the operating system's API with superuser privileges.
These flaws have affected major browsers including Firefox,[95] Internet Explorer,[96] and Safari.[97]
Plugins, such as video players, Adobe Flash, and the wide range of ActiveX controls enabled by default in Microsoft Internet Explorer, may also have flaws exploitable via JavaScript (such flaws have been exploited in the past).[98][99]
In Windows Vista, Microsoft has attempted to contain the risks of bugs such as buffer overflows by running the Internet Explorer process with limited privileges.[100] Google Chrome similarly confines its page renderers to their own "sandbox".
Sandbox implementation errors
[edit]Web browsers are capable of running JavaScript outside the sandbox, with the privileges necessary to, for example, create or delete files. Such privileges are not intended to be granted to code from the Web.
Incorrectly granting privileges to JavaScript from the Web has played a role in vulnerabilities in both Internet Explorer[101] and Firefox.[102] In Windows XP Service Pack 2, Microsoft demoted JScript's privileges in Internet Explorer.[103]
Microsoft Windows allows JavaScript source files on a computer's hard drive to be launched as general-purpose, non-sandboxed programs (see: Windows Script Host). This makes JavaScript (like VBScript) a theoretically viable vector for a Trojan horse, although JavaScript Trojan horses are uncommon in practice.[104][failed verification]
Hardware vulnerabilities
[edit]In 2015, a JavaScript-based proof-of-concept implementation of a rowhammer attack was described in a paper by security researchers.[105][106][107][108]
In 2017, a JavaScript-based attack via browser was demonstrated that could bypass ASLR. It is called "ASLR⊕Cache" or AnC.[109][110]
In 2018, the paper that announced the Spectre attacks against Speculative Execution in Intel and other processors included a JavaScript implementation.[111]
Development tools
[edit]Important tools have evolved with the language.
- Every major web browser has built-in web development tools, including a JavaScript debugger.
- Static program analysis tools, such as ESLint and JSLint, scan JavaScript code for conformance to a set of standards and guidelines.
- Some browsers have built-in profilers. Stand-alone profiling libraries have also been created, such as benchmark.js and jsbench.[112][113]
- Many text editors have syntax highlighting support for JavaScript code.
Related technologies
[edit]Java
[edit]A common misconception is that JavaScript is directly related to Java. Both indeed have a C-like syntax (the C language being their most immediate common ancestor language). They are also typically sandboxed, and JavaScript was designed with Java's syntax and standard library in mind. In particular, all Java keywords were reserved in original JavaScript, JavaScript's standard library follows Java's naming conventions, and JavaScript's Math and Date objects are based on classes from Java 1.0.[114]
Both languages first appeared in 1995, but Java was developed by James Gosling of Sun Microsystems and JavaScript by Brendan Eich of Netscape Communications.
The differences between the two languages are more prominent than their similarities. Java has static typing, while JavaScript's typing is dynamic. Java is loaded from compiled bytecode, while JavaScript is loaded as human-readable source code. Java's objects are class-based, while JavaScript's are prototype-based. Finally, Java did not support functional programming until Java 8, while JavaScript has done so from the beginning, being influenced by Scheme.
JSON
[edit]JSON is a data format derived from JavaScript; hence the name JavaScript Object Notation. It is a widely used format supported by many other programming languages.
Transpilers
[edit]Many websites are JavaScript-heavy, so transpilers have been created to convert code written in other languages, which can aid the development process.[36]
TypeScript and CoffeeScript are two notable languages that transpile to JavaScript.
WebAssembly
[edit]WebAssembly is a newer language with a bytecode format designed to complement JavaScript, especially the performance-critical portions of web page scripts. All of the major JavaScript engines support WebAssembly,[115] which runs in the same sandbox as regular JavaScript code.
asm.js is a subset of JavaScript that served as the forerunner of WebAssembly.[116]
Notes
[edit]References
[edit]- ^ a b "Netscape and Sun announce JavaScript, the Open, Cross-platform Object Scripting Language for Enterprise Networks and the Internet" (Press release). 4 December 1995. Archived from the original on 16 September 2007.
- ^ "ECMAScript® 2024 Language Specification". June 2024. Retrieved 30 August 2024.
- ^ "ECMAScript® 2025 Language Specification". 27 March 2024. Retrieved 17 April 2024.
- ^ "nodejs/node-eps". GitHub. Archived from the original on 29 August 2020. Retrieved 5 July 2018.
- ^ a b Seibel, Peter (16 September 2009). Coders at Work: Reflections on the Craft of Programming. Apress. ISBN 978-1-4302-1948-4. Archived from the original on 24 December 2020. Retrieved 25 December 2018.
Eich: The immediate concern at Netscape was it must look like Java.
- ^ a b c d e f "Chapter 4. How JavaScript Was Created". speakingjs.com. Archived from the original on 27 February 2020. Retrieved 21 November 2017.
- ^ "Popularity – Brendan Eich".
- ^ "Brendan Eich: An Introduction to JavaScript, JSConf 2010". YouTube. 20 January 2013. p. 22m. Archived from the original on 29 August 2020. Retrieved 25 November 2019.
Eich: "function", eight letters, I was influenced by AWK.
- ^ Eich, Brendan (1998). "Foreword". In Goodman, Danny (ed.). JavaScript Bible (3rd ed.). John Wiley & Sons. ISBN 0-7645-3188-3. LCCN 97078208. OCLC 38888873. OL 712205M.
- ^ a b "Usage Statistics of JavaScript as Client-side Programming Language on Websites". W3Techs. Retrieved 27 February 2024.
- ^ "Stack Overflow Developer Survey 2025". Stack Overflow. Retrieved 10 October 2025.
- ^ "ECMAScript 2020 Language Specification". Archived from the original on 8 May 2020. Retrieved 8 May 2020.
- ^ Enzer, Larry (31 August 2018). "The Evolution of the Web Browsers". Monmouth Web Developers. Archived from the original on 31 August 2018. Retrieved 31 August 2018.
- ^ a b c Fin JS (17 June 2016), "Brendan Eich – CEO of Brave", YouTube, retrieved 7 February 2018
- ^ "Netscape Communications Corp.", Browser enhancements. Encyclopædia Britannica 2006 Ultimate Reference Suite DVD
- ^ "TechVision: Innovators of the Net: Brendan Eich and JavaScript". Archived from the original on 8 February 2008.
- ^ a b Han, Sheon (4 March 2024). "JavaScript Runs the World—Maybe Even Literally". Wired. Retrieved 21 August 2024.
- ^ a b "Chapter 5. Standardization: ECMAScript". speakingjs.com. Archived from the original on 1 November 2021. Retrieved 1 November 2021.
- ^ a b Champeon, Steve (6 April 2001). "JavaScript, How Did We Get Here?". oreilly.com. Archived from the original on 19 July 2016. Retrieved 16 July 2016.
- ^ "Microsoft Internet Explorer 3.0 Beta Now Available". microsoft.com. Microsoft. 29 May 1996. Archived from the original on 24 November 2020. Retrieved 16 July 2016.
- ^ McCracken, Harry (16 September 2010). "The Unwelcome Return of "Best Viewed with Internet Explorer"". technologizer.com. Archived from the original on 23 June 2018. Retrieved 16 July 2016.
- ^ Baker, Loren (24 November 2004). "Mozilla Firefox Internet Browser Market Share Gains to 7.4%". Search Engine Journal. Archived from the original on 7 May 2021. Retrieved 8 May 2021.
- ^ Weber, Tim (9 May 2005). "The assault on software giant Microsoft". BBC News. Archived from the original on 25 September 2017.
- ^ "Big browser comparison test: Internet Explorer vs. Firefox, Opera, Safari and Chrome". PC Games Hardware. Computec Media AG. 3 July 2009. Archived from the original on 2 May 2012. Retrieved 28 June 2010.
- ^ Purdy, Kevin (11 June 2009). "Lifehacker Speed Tests: Safari 4, Chrome 2". Lifehacker. Archived from the original on 14 April 2021. Retrieved 8 May 2021.
- ^ "TraceMonkey: JavaScript Lightspeed, Brendan Eich's Blog". Archived from the original on 4 December 2015. Retrieved 22 July 2020.
- ^ "Mozilla asks, 'Are we fast yet?'". Wired. Archived from the original on 22 June 2018. Retrieved 18 January 2019.
- ^ "ECMAScript 6: New Features: Overview and Comparison". es6-features.org. Archived from the original on 18 March 2018. Retrieved 19 March 2018.
- ^ Professional Node.js: Building JavaScript Based Scalable Software Archived 2017-03-24 at the Wayback Machine, John Wiley & Sons, 01-Oct-2012
- ^ Sams Teach Yourself Node.js in 24 Hours Archived 2017-03-23 at the Wayback Machine, Sams Publishing, 05-Sep-2012
- ^ Lawton, George (19 July 2018). "The secret history behind the success of npm and Node". TheServerSide. Archived from the original on 2 August 2021. Retrieved 2 August 2021.
- ^ Brown, Paul (13 January 2017). "State of the Union: npm". Linux.com. Archived from the original on 2 August 2021. Retrieved 2 August 2021.
- ^ a b c Branscombe, Mary (4 May 2016). "JavaScript Standard Moves to Yearly Release Schedule; Here is What's New for ES16". The New Stack. Archived from the original on 16 January 2021. Retrieved 15 January 2021.
- ^ "The TC39 Process". tc39.es. Ecma International. Archived from the original on 7 February 2021. Retrieved 15 January 2021.
- ^ "ECMAScript proposals". TC39. Archived from the original on 4 December 2020. Retrieved 15 January 2021.
- ^ a b Ashkenas, Jeremy. "List of languages that compile to JS". GitHub. Archived from the original on 31 January 2020. Retrieved 6 February 2020.
- ^ "U.S. Trademark Serial No. 75026640". uspto.gov. United States Patent and Trademark Office. 6 May 1997. Archived from the original on 13 July 2021. Retrieved 8 May 2021.
- ^ "Legal Notices". oracle.com. Oracle Corporation. Archived from the original on 5 June 2021. Retrieved 8 May 2021.
- ^ "Oracle to buy Sun in $7.4-bn deal". The Economic Times. 21 April 2009.
- ^ Claburn, Thomas (17 September 2024). "Oracle urged again to give up JavaScript trademark". The Register. Retrieved 2 February 2025.
- ^ Krill, Paul (20 September 2024). "JavaScript community challenges Oracle's JavaScript trademark". InfoWorld.
- ^ a b c "Usage statistics of JavaScript libraries for websites". W3Techs. Retrieved 9 April 2021.
- ^ "Using jQuery with Bootstrap". clouddevs.com. 10 June 2019. Retrieved 17 March 2024.
- ^ "Vanilla JS". vanilla-js.com. 16 June 2020. Archived from the original on 16 June 2020. Retrieved 17 June 2020.
- ^ "Server-Side JavaScript Guide". oracle.com. Oracle Corporation. 11 December 1998. Archived from the original on 11 March 2021. Retrieved 8 May 2021.
- ^ Clinick, Andrew (14 July 2000). "Introducing JScript .NET". Microsoft Developer Network. Microsoft. Archived from the original on 10 November 2017. Retrieved 10 April 2018.
[S]ince the 1996 introduction of JScript version 1.0 ... we've been seeing a steady increase in the usage of JScript on the server—particularly in Active Server Pages (ASP)
- ^ a b Mahemoff, Michael (17 December 2009). "Server-Side JavaScript, Back with a Vengeance". readwrite.com. Archived from the original on 17 June 2016. Retrieved 16 July 2016.
- ^ "JavaScript for Acrobat". adobe.com. 7 August 2009. Archived from the original on 7 August 2009. Retrieved 18 August 2009.
- ^ treitter (2 February 2013). "Answering the question: "How do I develop an app for GNOME?"". livejournal.com. Archived from the original on 11 February 2013. Retrieved 7 February 2013.
- ^ Ponge, Julien (19 April 2018). "Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM". oracle.com. Oracle Corporation. Retrieved 17 February 2025.
- ^ "Migration Guide from Nashorn to GraalJS". graalvm.org. Retrieved 17 February 2025.
- ^ "GraalJS". GraalVM. Retrieved 17 February 2025.
- ^ "Java Interoperability". oracle.com. Oracle. Retrieved 17 February 2025.
- ^ "Tessel 2... Leverage all the libraries of Node.JS to create useful devices in minutes with Tessel". tessel.io. Archived from the original on 26 May 2021. Retrieved 8 May 2021.
- ^ "Node.js Raspberry Pi GPIO Introduction". w3schools.com. Archived from the original on 13 August 2021. Retrieved 3 May 2020.
- ^ "Espruino – JavaScript for Microcontrollers". espruino.com. Archived from the original on 1 May 2020. Retrieved 3 May 2020.
- ^ Looper, Jen (21 September 2015). "A Guide to JavaScript Engines for Idiots". Telerik Developer Network. Archived from the original on 8 December 2018. Retrieved 8 December 2018.
- ^ "How Blink Works". Retrieved 12 March 2024.
- ^ a b "Documentation · V8". Google. Retrieved 3 March 2024.
- ^ Nelaturu, Keerthi (September 2020). "WebAssembly: What's the big deal?". medium.com. Retrieved 3 March 2024.
- ^ "Concurrency model and Event Loop". Mozilla Developer Network. Archived from the original on 5 September 2015. Retrieved 28 August 2015.
- ^ Flanagan, David (17 August 2006). JavaScript: The Definitive Guide. O'Reilly Media, Inc. p. 16. ISBN 978-0-596-55447-7. Archived from the original on 1 August 2020. Retrieved 29 March 2019.
- ^ a b c d Korolev, Mikhail (1 March 2019). "JavaScript quirks in one image from the Internet". The DEV Community. Archived from the original on 28 October 2019. Retrieved 28 October 2019.
- ^ "Proposal-bigint/ADVANCED.md at master · tc39/Proposal-bigint". GitHub.
- ^ Bernhardt, Gary (2012). "Wat". Destroy All Software. Archived from the original on 28 October 2019. Retrieved 28 October 2019.
- ^ "JavaScript data types and data structures". MDN. 16 February 2017. Archived from the original on 14 March 2017. Retrieved 24 February 2017.
- ^ Flanagan 2006, pp. 176–178.
- ^ Crockford, Douglas. "Prototypal Inheritance in JavaScript". Archived from the original on 13 August 2013. Retrieved 20 August 2013.
- ^ "Inheritance and the prototype chain". Mozilla Developer Network. Archived from the original on 25 April 2013. Retrieved 6 April 2013.
- ^ Herman, David (2013). Effective JavaScript. Addison-Wesley. p. 83. ISBN 978-0-321-81218-6.
- ^ Ghandi, Raju (2019). JavaScript Next. New York City: Apress Media. pp. 159–171. ISBN 978-1-4842-5394-6.
- ^ a b Haverbeke, Marijn (September 2024). Eloquent JavaScript (PDF) (4th ed.). San Francisco: No Starch Press. pp. 97–98. ISBN 978-1-71850-411-0. Archived (PDF) from the original on 12 March 2025.
- ^ Katz, Yehuda (12 August 2011). "Understanding "Prototypes" in JavaScript". Archived from the original on 5 April 2013. Retrieved 6 April 2013.
- ^ Herman, David (2013). Effective JavaScript. Addison-Wesley. pp. 125–127. ISBN 978-0-321-81218-6.
- ^ "Function – JavaScript". MDN Web Docs. Retrieved 30 October 2021.
- ^ "Properties of the Function Object". Es5.github.com. Archived from the original on 28 January 2013. Retrieved 26 May 2013.
- ^ Flanagan 2006, p. 141.
- ^ The many talents of JavaScript for generalizing Role-Oriented Programming approaches like Traits and Mixins Archived 2017-10-05 at the Wayback Machine, Peterseliger.blogspot.de, April 11, 2014.
- ^ Traits for JavaScript Archived 2014-07-24 at the Wayback Machine, 2010.
- ^ "Home | CocktailJS". Cocktailjs.github.io. Archived from the original on 4 February 2017. Retrieved 24 February 2017.
- ^ Croll, Angus (31 May 2011). "A fresh look at JavaScript Mixins". JavaScript, JavaScript…. Archived from the original on 15 April 2020.
- ^ "E4X – Archive of obsolete content". Mozilla Developer Network. Mozilla Foundation. 14 February 2014. Archived from the original on 24 July 2014. Retrieved 13 July 2014.
- ^ "var – JavaScript". The Mozilla Developer Network. Archived from the original on 23 December 2012. Retrieved 22 December 2012.
- ^ "let". MDN web docs. Mozilla. Archived from the original on 28 May 2019. Retrieved 27 June 2018.
- ^ "const". MDN web docs. Mozilla. Archived from the original on 28 June 2018. Retrieved 27 June 2018.
- ^ "Making JavaScript Safe for Advertising". ADsafe. Archived from the original on 6 July 2021. Retrieved 8 May 2021.
- ^ "Secure ECMA Script (SES)". Archived from the original on 15 May 2013. Retrieved 26 May 2013.
- ^ "Google Caja Project". Google. Archived from the original on 22 January 2021. Retrieved 9 July 2021.
- ^ "Mozilla Cross-Site Scripting Vulnerability Reported and Fixed – MozillaZine Talkback". Mozillazine.org. Archived from the original on 21 July 2011. Retrieved 24 February 2017.
- ^ Kottelin, Thor (17 June 2008). "Right-click "protection"? Forget about it". blog.anta.net. Archived from the original on 9 August 2011. Retrieved 28 July 2022.
- ^ Rehorik, Jan (29 November 2016). "Why You Should Never Put Sensitive Data in Your JavaScript". ServiceObjects Blog. ServiceObjects. Archived from the original on 3 June 2019. Retrieved 3 June 2019.
- ^ a b Lauinger, Tobias; Chaabane, Abdelberi; Arshad, Sajjad; Robertson, William; Wilson, Christo; Kirda, Engin (21 December 2016), "Thou Shalt Not Depend on Me: Analysing the Use of Outdated JavaScript Libraries on the Web" (PDF), Northeastern University, arXiv:1811.00918, doi:10.14722/ndss.2017.23414, ISBN 978-1-891562-46-4, S2CID 17885720, archived from the original (PDF) on 29 March 2017, retrieved 28 July 2022
- ^ Collins, Keith (27 March 2016). "How one programmer broke the internet by deleting a tiny piece of code". Quartz. Archived from the original on 22 February 2017. Retrieved 22 February 2017.
- ^ SC Magazine UK, Developer's 11 lines of deleted code 'breaks the internet' Archived February 23, 2017, at the Wayback Machine
- ^ Mozilla Corporation, Buffer overflow in crypto.signText() Archived 2014-06-04 at the Wayback Machine
- ^ Festa, Paul (19 August 1998). "Buffer-overflow bug in IE". CNET. Archived from the original on 25 December 2002.
- ^ SecurityTracker.com, Apple Safari JavaScript Buffer Overflow Lets Remote Users Execute Arbitrary Code and HTTP Redirect Bug Lets Remote Users Access Files Archived 2010-02-18 at the Wayback Machine
- ^ SecurityFocus, Microsoft WebViewFolderIcon ActiveX Control Buffer Overflow Vulnerability Archived 2011-10-11 at the Wayback Machine
- ^ Fusion Authority, Macromedia Flash ActiveX Buffer Overflow Archived August 13, 2011, at the Wayback Machine
- ^ "Protected Mode in Vista IE7 – IEBlog". Blogs.msdn.com. 9 February 2006. Archived from the original on 23 January 2010. Retrieved 24 February 2017.
- ^ US CERT, Vulnerability Note VU#713878: Microsoft Internet Explorer does not properly validate source of redirected frame Archived 2009-10-30 at the Wayback Machine
- ^ Mozilla Foundation, Mozilla Foundation Security Advisory 2005–41: Privilege escalation via DOM property overrides Archived 2014-06-04 at the Wayback Machine
- ^ Andersen, Starr (9 August 2004). "Part 5: Enhanced Browsing Security". TechNet. Microsoft Docs. Changes to Functionality in Windows XP Service Pack 2. Retrieved 20 October 2021.
- ^ For one example of a rare JavaScript Trojan Horse, see Symantec Corporation, JS.Seeker.K Archived 2011-09-13 at the Wayback Machine
- ^ Gruss, Daniel; Maurice, Clémentine; Mangard, Stefan (24 July 2015). "Rowhammer.js: A Remote Software-Induced Fault Attack in JavaScript". arXiv:1507.06955 [cs.CR].
- ^ Jean-Pharuns, Alix (30 July 2015). "Rowhammer.js Is the Most Ingenious Hack I've Ever Seen". Motherboard. Vice. Archived from the original on 27 January 2018. Retrieved 26 January 2018.
- ^ Goodin, Dan (4 August 2015). "DRAM 'Bitflipping' exploit for attacking PCs: Just add JavaScript". Ars Technica. Archived from the original on 27 January 2018. Retrieved 26 January 2018.
- ^ Auerbach, David (28 July 2015). "Rowhammer security exploit: Why a new security attack is truly terrifying". slate.com. Archived from the original on 30 July 2015. Retrieved 29 July 2015.
- ^ AnC Archived 2017-03-16 at the Wayback Machine VUSec, 2017
- ^ New ASLR-busting JavaScript is about to make drive-by exploits much nastier Archived 2017-03-16 at the Wayback Machine Ars Technica, 2017
- ^ Spectre Attack Archived 2018-01-03 at the Wayback Machine Spectre Attack
- ^ "Benchmark.js". benchmarkjs.com. Archived from the original on 19 December 2016. Retrieved 6 November 2016.
- ^ JSBEN.CH. "JSBEN.CH Performance Benchmarking Playground for JavaScript". jsben.ch. Archived from the original on 27 February 2021. Retrieved 13 August 2021.
- ^ Eich, Brendan (3 April 2008). "Popularity". Archived from the original on 3 July 2011. Retrieved 19 January 2012.
- ^ "Edge Browser Switches WebAssembly to 'On' -- Visual Studio Magazine". Visual Studio Magazine. Archived from the original on 10 February 2018. Retrieved 9 February 2018.
- ^ "frequently asked questions". asm.js. Archived from the original on 4 June 2014. Retrieved 13 April 2014.
Further reading
[edit]- Flanagan, David (2020). JavaScript: The Definitive Guide (7th ed.). Sebastopol, California: O'Reilly. ISBN 978-1-491-95202-3.
- Haverbeke, Marijn (2024). Eloquent JavaScript (PDF) (4th ed.). San Francisco: No Starch Press. ISBN 978-1-71850-411-0. Archived (PDF) from the original on 12 March 2025.
- Zakas, Nicholas (2014). Principles of Object-Oriented JavaScript (1st ed.). No Starch Press. ISBN 978-1-59327-540-2.
External links
[edit]- The Modern JavaScript Tutorial. A community maintained continuously updated collection of tutorials on the entirety of the language.
- "JavaScript: The First 20 Years". Retrieved 6 February 2022.
JavaScript
View on GrokipediaHistory
Origins at Netscape
JavaScript originated in the mid-1990s at Netscape Communications Corporation, where Brendan Eich, a newly hired developer, was tasked with creating a scripting language for the web browser. In early to mid-May 1995, Eich prototyped the language under the code name Mocha, drawing inspiration from existing languages like Scheme and Self for its prototype-based object model.[8][9] By late 1995, amid internal discussions and to align with Netscape's strategic partnerships, the name was changed first to LiveScript and then to JavaScript in December, partly to capitalize on the rising popularity of Sun Microsystems' Java programming language, with its syntax adopted for developer familiarity.[8][2] The language was rapidly integrated into Netscape Navigator 2.0, debuting in the browser's beta releases starting in September 1995, with the JavaScript name appearing in Beta 3 that December.[8][2] This marked JavaScript's first public implementation as a client-side scripting tool embedded directly in the browser, allowing developers to enhance HTML documents without requiring server-side processing or additional plugins.[9] Netscape designed JavaScript primarily to enable dynamic and interactive web experiences, addressing the limitations of static HTML pages prevalent at the time. Its core objectives included supporting interactive web forms for user input validation, simple animations to bring pages to life, and basic client-side logic to perform computations and decisions directly in the browser, thereby reducing the need for roundtrips to the server.[9][8] Among its inaugural features, JavaScript introduced rudimentary event handling to respond to user interactions, such as mouse clicks or form submissions, and early prototypes for manipulating the Document Object Model (DOM), which allowed scripts to access and modify HTML elements dynamically.[9] These capabilities laid the groundwork for more responsive web interfaces, though the initial implementation was basic and tied closely to Netscape's proprietary extensions.[8]Early Adoption and Standardization
Following the initial release of JavaScript in Netscape Navigator 2.0, Microsoft responded by developing its own implementation, JScript, which was introduced with Internet Explorer 3.0 on August 13, 1996.[10] This move intensified the "browser wars" between Netscape and Microsoft, as each company extended the language with proprietary features to gain competitive advantage, resulting in significant compatibility issues for web developers who had to write version-specific code for different browsers.[11] To mitigate these fragmentation risks and promote interoperability, Netscape submitted JavaScript to Ecma International for standardization in November 1996.[12] The effort culminated in the first edition of the ECMAScript standard (ES1, ECMA-262), approved in June 1997, which defined the core syntax, semantics, and behavior of the language while aligning implementations from Netscape and Microsoft.[13] JavaScript's adoption surged during the dot-com boom of the late 1990s, as the explosive growth of the web—fueled by rising internet users and online businesses—demanded more interactive experiences beyond static HTML pages.[14] Developers increasingly used it for client-side enhancements in dynamic websites, such as real-time form validation in e-commerce applications, which improved user interaction by checking inputs like email addresses or credit card numbers without server round-trips.[15] Subsequent standardization efforts refined the language: the second edition (ES2) was released in August 1998, primarily incorporating editorial clarifications and minor alignments to international standards without adding new features.[16] The third edition (ES3), published in December 1999, introduced key capabilities including regular expressions for pattern matching in strings and try-catch blocks for structured exception handling, enhancing error management and text processing in web scripts.[17]Maturation and Modern Evolution
By the late 1990s, JavaScript's popularity waned amid the browser wars, where incompatibilities between Netscape Navigator and Internet Explorer implementations led to fragmented support and developer frustration with its error-prone nature.[18] This decline reversed in 2005 with the rise of Ajax, driven by the standardization of the XMLHttpRequest API, which enabled dynamic web applications without full page reloads and reignited interest in client-side scripting.[19] The release of ECMAScript 5 (ES5) in December 2009 marked a significant maturation, introducing strict mode for enhanced error checking, native JSON support for data interchange, and new array methods such as forEach, map, and filter to simplify iteration and manipulation.[20] These additions improved code reliability and interoperability across browsers, laying groundwork for more robust web development. ECMAScript 6 (ES2015), finalized in June 2015, represented a revolutionary update by incorporating object-oriented classes, concise arrow functions for lexical this binding, promises for asynchronous programming, and native modules for better code organization.[21] Following this, the ECMAScript specification shifted to annual releases; for instance, ES2020 introduced BigInt for arbitrary-precision integers beyond the Number type's limits, while ES2023 added immutable array methods like toSorted, toReversed, and with to promote safer data handling without mutating originals.[22] To bridge gaps in browser support for these evolving features, transpilers like Babel emerged around 2015, converting modern syntax—such as arrow functions and classes—into ES5-compatible code while integrating polyfills for runtime behaviors like promises.[23] Concurrently, Node.js, first released in 2009 by Ryan Dahl, expanded JavaScript to server-side environments using the V8 engine, enabling full-stack development and powering scalable applications like Netflix's streaming backend.[24] In the 2020s, JavaScript's ecosystem continued advancing with proposals for deeper hardware integration, including WebGPU—a W3C Candidate Recommendation API since 2023—that allows JavaScript access to GPU compute shaders for graphics and machine learning tasks directly in browsers.[25] Additionally, the Temporal API, which reached stage 3 in the TC39 process in March 2021 and has remained at that stage through 2025, previews a comprehensive overhaul of date and time handling in ES2025, offering immutable, time-zone-aware objects to replace the legacy Date constructor's limitations.[26]Branding and Standards
Trademark and Naming
The name "JavaScript" originated in 1995 when Netscape Communications Corporation, in partnership with Sun Microsystems, rebranded its scripting language from LiveScript to capitalize on the popularity of Sun's Java programming language, despite no technical relation between the two.[27] The language had initially been developed by Brendan Eich at Netscape under the codename Mocha earlier that year, before the interim name LiveScript.[9] This marketing-driven renaming was part of a licensing agreement between Netscape and Sun, allowing Netscape to use the "JavaScript" name to evoke synergy with Java's emerging brand.[27] Sun Microsystems formally applied for the "JavaScript" trademark with the United States Patent and Trademark Office (USPTO) in December 1995, with registration granted on December 26, 2000 (Serial No. 75026640).[28] Following Oracle Corporation's acquisition of Sun in 2010, Oracle inherited ownership of the trademark.[29] Oracle has since licensed the "JavaScript" name to entities like the Mozilla Foundation for their implementations. However, as of November 2025, the trademark's status is under challenge through a pending cancellation proceeding filed on November 22, 2024 (announced publicly on November 25, 2024), by Deno Land Inc., arguing that "JavaScript" has become generic; the case remains unresolved following Oracle's responses and procedural delays.[28][30][31][32] Oracle maintains it as a proprietary brand distinct from the open standard.[33] To distinguish the standardized specification from the trademarked brand and avoid confusion with the unrelated Java trademark (also owned by Oracle), the European standards body Ecma International adopted "ECMAScript" as the official name for the language standard in 1997.[33] Usage guidelines emphasize referring to the standard as ECMAScript, reserving "JavaScript" for Netscape- and Mozilla-derived implementations, thereby preventing brand dilution or legal conflicts with Java.[33] When Microsoft developed its ECMAScript implementation in 1996, it named it JScript to sidestep potential trademark infringement claims from Netscape and Sun regarding "JavaScript." This approach aligned with the push toward standardization, culminating in Microsoft's participation in the Ecma process, which helped unify browser scripting without direct trademark disputes.[34]ECMAScript Specification Process
The ECMAScript specification is developed and maintained by Ecma Technical Committee 39 (TC39), a working group under Ecma International responsible for evolving the language through consensus-driven processes.[35] TC39 oversees the annual release of new ECMAScript editions, incorporating features via a structured proposal pipeline that ensures rigorous review and implementation feasibility. Proposals advance through five stages: Stage 0 (strawperson) for initial ideation without formal committee endorsement; Stage 1 for establishing a proposal with a champion and addressing key concerns; Stage 2 for drafting a preferred solution with preliminary specification text; Stage 3 for candidate status, where the feature is deemed complete for implementation with minimal further changes; and Stage 4 for finished proposals ready for inclusion in the standard, requiring at least two independent implementations and comprehensive tests.[35] This process promotes transparency and collaboration, with all discussions and documents publicly available on GitHub repositories under the TC39 organization.[36] Key historical milestones shaped the modern specification process. In 2008, efforts to develop ECMAScript 4 (ES4) were abandoned due to disagreements over its increased complexity and potential for fragmentation among implementations, leading instead to the more incremental ECMAScript 5 (ES5) released in 2009, which focused on harmonizing existing features while adding strict mode and JSON support.[37] Following ES5, the process evolved significantly with ECMAScript 2015 (ES6), introducing major enhancements like classes and modules; this paved the way for a shift to annual releases starting with ECMAScript 2016, allowing for steady, predictable evolution rather than infrequent large updates.[38] Throughout these changes, backward compatibility has remained a foundational principle, ensuring that new editions do not break existing codebases unless explicitly addressing legacy issues, as emphasized in TC39's guidelines for proposal advancement.[35] Contributions to the specification come from a diverse set of delegates, including representatives from major browser vendors such as Google (V8 engine), Apple (JavaScriptCore), and Mozilla (SpiderMonkey), alongside other Ecma members like Microsoft and IBM.[39] The community plays a vital role through public GitHub repositories, where anyone can submit ideas, review drafts, or contribute tests via the Test262 suite, fostering broad input beyond corporate stakeholders.[40] Since the 2010s, TC39 has intensified inclusivity efforts, adopting a Code of Conduct in 2017 to promote diversity by welcoming participants from varied backgrounds and prohibiting discrimination, with a dedicated committee to handle reports and ensure safe collaboration spaces.[41] As of November 2025, the process continues to prioritize backward compatibility while advancing innovative features; for instance, the Temporal proposal for improved date and time handling remains in Stage 3, undergoing implementation testing before potential inclusion in a future edition.[26] This ongoing cadence reflects TC39's commitment to balancing evolution with stability, enabling JavaScript to adapt to modern needs without disrupting its vast ecosystem.[38]Usage Contexts
Client-Side Web Development
JavaScript serves as the primary scripting language for client-side web development, enabling dynamic interactivity within web browsers by allowing developers to manipulate the Document Object Model (DOM) and respond to user events. The DOM represents the structured representation of HTML documents as a tree of objects, which JavaScript accesses through built-in browser APIs to create, modify, or delete elements, attributes, and content without requiring full page reloads.[42] This manipulation facilitates real-time updates to user interfaces, such as inserting new elements or altering text and styles in response to user actions. Event listeners are a core mechanism in JavaScript for handling user interactions, such as mouse clicks, keyboard inputs, and form submissions, by attaching callback functions to DOM elements via theaddEventListener() method.[43] For instance, developers can use event listeners to validate form inputs on submission, checking for required fields or valid formats before processing, which improves user experience by providing immediate feedback without server round-trips. Another common application involves triggering CSS transitions or animations through JavaScript, where an event like a button click adds or removes CSS classes to smoothly animate elements, leveraging hardware-accelerated rendering for efficiency.[44] In single-page applications (SPAs), JavaScript integrates with the History API to manage navigation states, using methods like pushState() and popstate events to update the URL and content dynamically while maintaining browser back/forward functionality.[45]
JavaScript integrates seamlessly with HTML and CSS to form the foundational triad of web development, where scripts interact with HTML structures and CSS styles to produce responsive pages. Early practices often embedded JavaScript directly within HTML using inline <script> tags, but this approach led to parsing delays and hindered caching, prompting a shift to external .js files linked via <script src> attributes, which browsers can cache across sessions for improved load times and maintainability.[46] Modern best practices recommend deferring or asynchronously loading these external scripts to avoid blocking HTML rendering, further enhancing performance.
Support for JavaScript is universal across all modern web browsers, including Chrome, Firefox, Safari, and Edge, ensuring consistent execution of core features like DOM manipulation and event handling without additional configuration. For legacy browsers lacking support for newer APIs, polyfills—JavaScript implementations that emulate missing functionality—can be included to bridge compatibility gaps, though their use has diminished as older browsers like Internet Explorer fade from relevance.[47] Key browser-provided APIs further extend JavaScript's capabilities in client-side contexts; for example, the Canvas API enables 2D drawing and graphics rendering directly in the browser, supporting applications from simple charts to complex games.[48] Similarly, the Fetch API provides a modern, promise-based interface for making HTTP requests, replacing older methods like XMLHttpRequest for asynchronous data retrieval and manipulation.[49]
Server-Side and Non-Web Environments
JavaScript, originally designed for client-side web scripting, has expanded significantly into server-side and non-web environments through dedicated runtimes and frameworks that leverage its asynchronous capabilities. Node.js, released in 2009 by Ryan Dahl, pioneered server-side JavaScript by providing an event-driven, non-blocking I/O model built on the V8 engine, enabling efficient handling of concurrent operations for applications like web servers, RESTful APIs, and command-line tools.[24][50] This architecture allows Node.js to process thousands of simultaneous connections without traditional threading, making it ideal for scalable backend services. Modern alternatives like Deno and Bun address some of Node.js's limitations, such as module resolution and security. Deno, introduced in 2018, offers secure-by-default execution with explicit permission prompts for file, network, and environment access, alongside zero-configuration TypeScript support.[51][52] Bun, launched in 2022, emphasizes speed with its JavaScriptCore engine and includes native TypeScript transpilation, a built-in bundler, and package manager for faster development workflows.[53][54] Beyond servers, JavaScript powers non-web applications across diverse platforms. For desktop software, Electron combines Chromium and Node.js to build cross-platform apps using web technologies; notable examples include Visual Studio Code, which relies on Electron for its interface and extensibility.[55][56] In mobile development, React Native enables native iOS and Android apps with JavaScript and React components, bridging to platform-specific UI elements for high-performance experiences.[57] For embedded systems and IoT, frameworks like Johnny-Five provide a JavaScript API for hardware interaction, supporting Arduino, Raspberry Pi, and sensors in robotics projects.[58] As of 2025, JavaScript's backend adoption remains strong, with the Stack Overflow Developer Survey indicating that 29.7% of developers used Node.js in the past year, reflecting its role in full-stack and serverless architectures.[59] For instance, Netflix employs Node.js-based serverless functions in its Functions-as-a-Service runtime to manage API platforms, handling high-scale microservices efficiently.[60]Execution Model
JavaScript Engines
JavaScript engines are the core software components responsible for parsing, compiling, and executing JavaScript code within browsers and other environments. These engines translate high-level JavaScript source code into machine-executable instructions, enabling dynamic interpretation or compilation at runtime to achieve both flexibility and performance. Modern engines predominantly employ just-in-time (JIT) compilation, which combines interpretation for quick startup with on-the-fly compilation of frequently executed code paths into optimized native machine code, significantly boosting execution speed compared to pure interpretation.[61] Prominent examples include Google's V8 engine, released in 2008 alongside Chrome and also powering Node.js, which uses a multi-tier JIT approach starting with an interpreter called Ignition that generates bytecode, followed by the TurboFan optimizing compiler for hot code paths. Mozilla's SpiderMonkey, originally developed in 1995 for Netscape Navigator and now integral to Firefox, employs tiered JIT compilation with a baseline interpreter, a baseline compiler for initial optimizations, and higher-tier compilers like WarpMonkey for aggressive inlining and machine code generation. Apple's JavaScriptCore, introduced in 2005 for Safari, similarly relies on JIT techniques, including early adoption of baseline and optimizing compilers to handle dynamic language features efficiently. These engines demonstrate JIT's role in adapting to JavaScript's dynamic typing by profiling runtime behavior and recompiling as needed.[62][63][64] The execution pipeline in these engines begins with lexical analysis, where source code is tokenized into identifiers, operators, and literals, followed by parsing to construct an abstract syntax tree (AST) representing the code's syntactic structure. The AST is then transformed into intermediate bytecode, a platform-independent representation suitable for interpretation, before JIT stages apply optimizations such as inline caching, which stores type and property access assumptions in caches to accelerate polymorphic operations without full recompilation. For instance, inline caching enables engines to predict and specialize property lookups based on observed types, deoptimizing and falling back if assumptions fail, thus balancing speed and correctness in dynamic contexts.[61] Performance advancements continue to drive engine evolution, exemplified by V8's TurboFan optimizer, enabled by default in 2017, which employs a "sea of nodes" intermediate representation for sophisticated graph-based optimizations, resulting in faster execution for complex workloads like those in modern web applications. Benchmarks such as JetStream evaluate these improvements by measuring latency, throughput, and geometric means across JavaScript and WebAssembly tests, highlighting engines' ability to handle real-world scenarios with quick startup and sustained performance. Cross-engine compatibility is maintained through rigorous adherence to the ECMAScript standard, verified via the official Test262 conformance test suite, which includes over 50,000 tests covering specification behaviors to ensure consistent implementation across engines.[65][66][40]Runtime and Concurrency
JavaScript operates in a single-threaded execution model within its runtime environment, where code is processed sequentially on a primary thread. This model employs a call stack to manage function invocations and execution contexts, pushing new frames onto the stack when functions are called and popping them upon completion. Objects and data structures are allocated in a heap, a separate memory area that persists beyond the stack's lifecycle. Asynchronous operations are handled by an event loop, which continuously checks for completed tasks in a job queue and executes them only when the call stack is empty, ensuring the runtime remains responsive.[67] To achieve concurrency without blocking the main thread, JavaScript relies on non-blocking I/O mechanisms. Early approaches used callbacks to defer execution until asynchronous tasks, such as network requests, complete. Promises, introduced in ECMAScript 2015, provide a structured way to handle asynchronous results, allowing chaining of thenable operations for cleaner code. The async/await syntax, added in ECMAScript 2017, further simplifies this by enabling synchronous-like code for promise-based operations, reducing callback hell while maintaining non-blocking behavior. For true parallelism in browser environments, Web Workers allow scripts to run in background threads isolated from the main thread, enabling concurrent computation without direct DOM access, though communication occurs via message passing.[68][69][70] Memory management in JavaScript runtimes is automated through garbage collection, which identifies and reclaims memory occupied by unreachable objects. In the V8 engine, used by Chrome and Node.js, a generational garbage collector divides the heap into young and old spaces, applying mark-and-sweep algorithms to trace live objects from roots and sweep away the rest. This approach minimizes pauses by focusing frequent, short collections on short-lived objects in the young generation, with incremental marking in the old generation to reduce latency.[71] Runtime environments impose distinct constraints on execution. In browsers, JavaScript runs in a sandboxed context with access limited to web APIs like the DOM and no direct file system interaction, using the globalwindow object. Node.js, in contrast, provides a server-side global scope with built-in modules for file I/O and networking, supporting both CommonJS and ES modules without browser-specific globals. As of 2025, proposals for enhanced shared memory features, such as shared structs, remain at stage 2 in the TC39 process, aiming to expand multithreading capabilities beyond current Atomics and SharedArrayBuffer.[72][73]
Core Features
Data Types and Typing
JavaScript, governed by the ECMAScript specification, defines seven primitive data types and one composite type for its values.[74] The primitive types include Undefined, Null, Boolean, Number, BigInt, String, and Symbol, each representing simple, immutable values without internal structure.[74] These primitives form the foundational building blocks for all data manipulation in the language, ensuring efficient handling of basic values like truth values, text, and numbers.[74] The Undefined type has a single value,undefined, which indicates an uninitialized or absent variable.[74] The Null type also holds one value, null, denoting the intentional absence of any object or non-primitive value.[74] Boolean primitives are either true or false, used to represent logical conditions.[74] The Number type employs the double-precision 64-bit format specified in IEEE 754-2008, accommodating finite values from approximately -1.8 × 10^308 to 1.8 × 10^308, along with special values like NaN (Not-a-Number), positive and negative infinity, and signed zero.[74] Introduced in ECMAScript 2020, BigInt provides arbitrary-precision integers without a fixed bit width, enabling exact representation of large whole numbers beyond Number's safe integer limit of 2^53 - 1.[74][75] Strings are immutable sequences of 16-bit unsigned integer code units, typically UTF-16 encoded, with a maximum length of 2^53 - 1 characters, suitable for text data.[74] Symbols, added in ECMAScript 2015 (ES6), are unique and immutable primitives primarily used as non-enumerable keys for object properties to prevent naming collisions.[74][76]
In contrast, the Object type is the sole composite type, serving as a mutable collection of named properties accessible via string or symbol keys, which can hold primitive or other object values.[74] Objects encompass specialized subtypes such as arrays (ordered collections), functions (executable objects), and regular expressions, all inheriting from a shared prototype chain.[74] To inspect types at runtime, JavaScript provides the typeof operator, which returns a string indicating the primitive type of its operand (e.g., "number" for numeric values, "object" for null and non-primitives), though it cannot distinguish object subtypes. For checking object inheritance or constructor relationships, the instanceof operator evaluates whether an object inherits from a specified constructor, useful for subtype verification.
JavaScript employs dynamic typing, where variables are not bound to specific types at compile time and can hold values of any type during execution. This is complemented by weak typing, characterized by implicit type coercion during operations on mixed types, such as converting operands via abstract operations like ToPrimitive, ToNumber, or ToString.[77] For instance, the expression "1" + 1 coerces the number to a string, yielding "11", while 1 + true treats the boolean as 1, resulting in 2.[78] To mitigate coercion pitfalls, strict equality (===) compares both value and type without conversion, returning false for "1" === 1. Prior to ECMAScript 2015, JavaScript lacked class syntax, relying solely on structural typing via prototypes; ES6 introduced classes as syntactic sugar over prototypes, offering nominal typing hints through instanceof checks against class constructors.
// Example of type checks
typeof 42; // "number"
typeof Symbol(); // "symbol"
typeof {}; // "object"
42n instanceof BigInt; // false (BigInt is primitive)
new Date() instanceof Date; // true
"1" === 1; // false (strict equality avoids coercion)
// Example of type checks
typeof 42; // "number"
typeof Symbol(); // "symbol"
typeof {}; // "object"
42n instanceof BigInt; // false (BigInt is primitive)
new Date() instanceof Date; // true
"1" === 1; // false (strict equality avoids coercion)
Syntax and Control Structures
JavaScript syntax is influenced by languages such as C, Java, and Perl, featuring a flexible structure that emphasizes readability and ease of use in scripting contexts.[79] The language employs statements as the fundamental units of execution, which can be terminated by semicolons or inferred through automatic semicolon insertion (ASI), a mechanism that adds semicolons where the parser anticipates line breaks to prevent errors.[80] Block statements are delimited by curly braces{} to define scope and group code, enabling conditional and iterative control flow.[79]
Variable declarations form the basis of data binding in JavaScript, using keywords var, let, or const. The var keyword, introduced in ECMAScript 1, declares variables with function or global scope and allows hoisting, where declarations are moved to the top of their scope during compilation, initializing to undefined.[81] In contrast, let and const, added in ECMAScript 2015 (ES6), provide block scoping, restricting visibility to the nearest enclosing block; they are hoisted but enter a temporal dead zone until declaration, throwing errors for premature access, and disallow redeclaration within the same scope. The const variant enforces constancy by requiring an initializer and preventing reassignment of the binding, though object properties can still be modified.[82][83]
Control structures facilitate decision-making and repetition in code execution. Conditional statements include if...else, which evaluates a condition and executes one of two blocks based on its truthiness—if (condition) { /* true block */ } else { /* false block */ }—and the switch statement for multi-way branching, matching an expression against case labels until a break or default clause intervenes: switch (expression) { case value1: /* statements */ break; default: /* statements */ }.[84][85] Looping constructs encompass for, which initializes, tests a condition, and updates per iteration—for (init; condition; update) { /* body */ }—alongside while and do...while for condition-based repetition: while (condition) { /* body */ } and do { /* body */ } while (condition);.[86][87] The ES6 for...of loop iterates over iterable objects like arrays, assigning values sequentially: for (const item of iterable) { /* body */ }.[88] Keywords break and continue manage loop and switch flow, exiting or skipping iterations respectively.
Expressions evaluate to values and include operators for computation and logic. Arithmetic operators handle numeric operations, with unary ++ (increment) and -- (decrement) modifying values either pre- or post-fix: let x = 5; x++; // x becomes 6, but expression returns 5.[89] Comparison operators distinguish loose equality (==), which coerces types—for instance, 3 == '3' yields true due to string-to-number conversion—and strict equality (===), requiring type identity: 3 === '3' is false. Logical operators && (AND) and || (OR) short-circuit evaluation, returning the first falsy or truthy operand respectively: true && false evaluates to false, but may return non-booleans like 0 || 'hello' yielding 'hello'.[90] The ternary operator provides concise conditionals: condition ? trueValue : falseValue.[91] Arrow functions, introduced in ES6, offer succinct syntax for defining functions: (params) => { /* body */ } or () => expression, preserving the enclosing scope's this binding unlike traditional functions.[92]
Comments enhance code documentation, using single-line // for inline notes or multi-line /* */ for blocks, with no support for nesting.[79] Strict mode, activated via "use strict"; directive at the top of a script or function, enforces stricter parsing and error handling, such as prohibiting undeclared variables and duplicate parameters, to promote safer coding practices.[93] This mode, available since ES5, helps catch common mistakes early without altering core syntax.[94]
Objects and Prototypes
In JavaScript, objects serve as fundamental data structures that function as unordered collections of key-value pairs, where keys are strings (or symbols) and values can be any data type, including other objects or functions. These objects enable dynamic property addition, modification, and deletion, supporting JavaScript's flexible, prototype-based programming model. Objects can be created in several ways: using object literals with curly braces{}, the Object.create() method for specifying a prototype, or constructor functions invoked with the new keyword. For instance, an object literal like const obj = { key: 'value' }; initializes a new object with the specified properties, while Object.create(null) creates an object without a prototype to avoid inheriting from Object.prototype. Constructor functions, such as function Person(name) { this.name = name; }, allow for reusable blueprints when instantiated as new Person('Alice').[95][96]
Central to JavaScript's object system is the prototype chain, a delegation mechanism that implements inheritance without classical class hierarchies. Every object has an internal [[Prototype]] link pointing to another object, typically its constructor's prototype property, forming a chain that resolves property lookups by traversing upward until null is reached. For example, an array instance links to Array.prototype, which in turn links to Object.prototype, allowing shared methods like toString() to be inherited across instances. This delegation-based inheritance means properties are resolved dynamically: if not found on the object itself, the search delegates to the prototype, promoting code reuse and mutability. Unlike classical inheritance, modifications to a prototype affect all delegating objects, and the chain can be inspected or modified via methods like Object.getPrototypeOf() or Object.setPrototypeOf().[97]
Object properties vary in configurability and visibility, with attributes controlling their behavior: enumerable properties can be iterated over (e.g., via for...in loops), while non-enumerable ones, often added by built-in methods, are excluded. Introduced in ECMAScript 5, getters and setters allow properties to compute values on access or modification using Object.defineProperty(), such as defining a getter that returns a calculated full name from first and last name fields. Utility methods like Object.keys(obj) return an array of enumerable own property names, excluding those from the prototype chain, while obj.hasOwnProperty('key') checks for direct ownership without traversing prototypes, preventing false positives from inherited properties. These features ensure precise control over object introspection and enumeration.[98][99]
ECMAScript 2015 (ES6) introduced classes as syntactic sugar over the existing prototype-based system, providing a more familiar object-oriented syntax without altering the underlying delegation model. Class declarations like class Rectangle { constructor(width, height) { this.width = width; this.height = height; } } compile to constructor functions with prototypal inheritance, where extends sets up the prototype chain between subclasses. The super() call within a subclass constructor or method invokes the parent class's corresponding method, ensuring proper initialization along the chain. Later, ECMAScript 2022 standardized private fields and methods using the # prefix, such as #privateField = 42;, which are inaccessible outside the class and stored directly on instances rather than the prototype, enhancing encapsulation while remaining true to the prototype model.[100][101]
Programming Paradigms
Functional Programming
JavaScript supports functional programming paradigms by treating functions as first-class citizens, enabling their use in higher-order operations, and providing language features that encourage immutability and composability.[102][5] These capabilities allow developers to write code that emphasizes declarative transformations over imperative mutations, drawing from functional principles while operating within JavaScript's dynamic environment. Functions in JavaScript are first-class objects, meaning they can be assigned to variables, passed as arguments to other functions, and returned from functions just like any other value.[102] This enables higher-order functions, where one function accepts or returns another, facilitating patterns such as callbacks and event handlers. For example, theArray.prototype.forEach method accepts a function as an argument to iterate over elements:
const numbers = [1, 2, 3];
numbers.forEach(num => console.log(num)); // Logs 1, 2, 3
const numbers = [1, 2, 3];
numbers.forEach(num => console.log(num)); // Logs 1, 2, 3
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
console.log(add5(2)); // Outputs 7
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
console.log(add5(2)); // Outputs 7
x from the outer scope, demonstrating closure's role in maintaining state across invocations.[103]
Pure functions, which produce the same output for the same input without side effects or mutations, are facilitated in JavaScript through built-in array methods introduced in ES5 that return new arrays rather than modifying the original.[104][105][106] The map(), filter(), and reduce() methods promote immutability by creating fresh data structures, aligning with functional principles where data transformation avoids in-place changes. JavaScript primitives like strings and numbers are inherently immutable, further supporting this approach by preventing direct modification.[107] An example of chaining these for a pure transformation:
const numbers = [1, 2, 3, 4];
const doubledEvens = numbers
.filter(n => n % 2 === 0)
.[map](/page/Map)(n => n * 2)
.reduce((sum, n) => sum + n, 0); // Results in 12 (4 + 8)
const numbers = [1, 2, 3, 4];
const doubledEvens = numbers
.filter(n => n % 2 === 0)
.[map](/page/Map)(n => n * 2)
.reduce((sum, n) => sum + n, 0); // Results in 12 (4 + 8)
numbers, emphasizing composable, side-effect-free operations central to functional programming.[106]
Currying and function composition in JavaScript can be achieved natively through partial application with the bind() method, which creates a new function with preset arguments. For a function like add(a, b), partial application yields a curried version: const addFive = add.[bind](/page/BIND)(null, 5);, allowing addFive(3) to return 8. Libraries such as Ramda extend these capabilities by providing explicit currying and composition utilities, enabling point-free styles and automatic partial application for more advanced functional pipelines.[108] Ramda's [curry](/page/Curry) transforms functions to accept arguments incrementally, while compose chains them right-to-left for readable data flows, promoting immutability and reusability in larger applications.[108]
Object-Oriented Programming
JavaScript employs a prototype-based approach to object-oriented programming, where objects inherit properties and methods from other objects via prototype chains rather than through rigid class hierarchies. This model allows for dynamic and flexible object creation and modification, enabling encapsulation, inheritance, and polymorphism without the need for explicit class definitions in early versions of the language. Introduced in ECMAScript editions and refined with syntactic sugar in ES6 (ECMAScript 2015), JavaScript's OOP facilitates reusable code structures while maintaining its dynamic nature.[109][38] Constructors in JavaScript are functions that initialize new object instances when invoked with thenew keyword, which creates an empty object, sets its prototype to the constructor's prototype property, binds this to the new instance, executes the constructor body, and returns the instance if no explicit return value is provided. For example, a constructor might define initial properties like function Person(name) { this.name = name; }, and instantiation occurs via const person = new Person("Alice");. The this keyword within constructor methods or instance methods refers to the current object instance, allowing access and modification of its properties, such as this.name in the example above; this binding is crucial for method calls on instances and changes context based on invocation (e.g., strict mode prevents implicit binding to the global object).[110][111][112]
Encapsulation in JavaScript hides internal state from external access, traditionally achieved through closures that scope variables privately within a function's lexical environment, or more directly via private fields introduced in ES2022, denoted by the # prefix and accessible only within the class declaration. For instance, a class might declare #privateData = 42; to restrict direct property access, enforcing data protection similar to access modifiers in other languages. Polymorphism is realized through dynamic method resolution, where property lookups traverse the prototype chain at runtime, allowing objects to respond to the same method call with behavior appropriate to their type, such as overriding a speak() method in subclasses without compile-time checks.[101][113]
Inheritance in JavaScript relies on prototype extension, where a derived constructor's prototype is linked to an instance of the base constructor (e.g., Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child;), enabling shared methods across instances. ES6 introduced the extends keyword for syntactic convenience in class declarations, creating a subclass that inherits from a superclass and requires super() calls in the constructor for initialization, as in class Child extends Parent { constructor() { super(); } }. Mixins, which compose multiple behaviors into a single object without deep inheritance, can be implemented using Object.assign() to copy properties from mixin objects onto a target prototype, such as Object.assign(Target.prototype, Mixin1, Mixin2);, providing horizontal reuse beyond single-parent inheritance. Prototype chains facilitate this by delegating unresolved property accesses to parent prototypes.[114][97]
Common design patterns in JavaScript adapt to its prototype model; the factory pattern uses functions or classes to create and return customized objects without exposing instantiation logic, for example, a createUser factory function that returns a configured instance based on parameters, leveraging constructors as object factories. The singleton pattern ensures a single instance by checking an exported variable or using an immediately invoked function expression (IIFE) to return a shared prototype-based object, such as const Singleton = (function() { const instance = Object.create(null); return { getInstance: () => instance }; })();. Unlike class-based languages like Java, where classes are blueprints separate from instances and inheritance is static with fixed hierarchies enforced at compile time, JavaScript's prototype delegation allows runtime modifications, treats objects and prototypes interchangeably, and supports ad-hoc extensions without formal interfaces or access modifiers, offering greater flexibility but requiring careful management to avoid unintended side effects.[115][96]
Other Paradigms
JavaScript supports several programming paradigms beyond functional and object-oriented approaches, including event-driven, reactive, procedural, and delegative styles, which enable flexible handling of asynchronous operations, state changes, and object composition.[38] Event-driven programming in JavaScript revolves around responding to events through observers and publish-subscribe patterns. The core mechanism is theaddEventListener method on EventTarget objects, which registers callback functions to handle specific events like user interactions or network responses.[43] For instance, to listen for a click on an element, one can use element.addEventListener('click', handlerFunction), allowing multiple listeners without overwriting existing ones.[43] Publish-subscribe patterns extend this using CustomEvent to create and dispatch custom events, decoupling publishers from subscribers; a publisher dispatches an event with dispatchEvent(new CustomEvent('myEvent', { detail: data })), while subscribers attach listeners to receive notifications.[116] This pattern is foundational in web applications for managing user interface interactions and is natively supported in browsers and Node.js environments.[117]
Reactive programming in JavaScript treats data streams and changes as observable sequences, facilitating declarative handling of asynchronous and event-based code. The RxJS library implements this paradigm using Observables, which represent streams of data that can be composed, transformed, and subscribed to, drawing from the ReactiveX standard.[118] For example, an Observable can filter and map events like mouse movements: fromEvent([document](/page/Document), 'mousemove').pipe(filter(e => e.clientX > 100), [map](/page/Map)(e => e.clientX)).subscribe(x => console.log(x)).[119] In modern frameworks, signals provide fine-grained reactivity; SolidJS, introduced in the 2020s, uses signals as reactive primitives where updates to a signal like createSignal(0) automatically propagate to dependent computations without virtual DOM diffing.[120] This approach emphasizes declarative updates over imperative state management, improving performance in user interfaces.[121]
Procedural programming in JavaScript manifests through imperative code sequences with side effects, where operations modify state directly via statements like assignments and loops.[122] This style is evident in scripts that perform sequential tasks, such as iterating over arrays with for loops to update external variables, allowing straightforward control flow but risking unintended mutations. Metaprogramming enhances this by intercepting object operations; introduced in ES6, the Proxy object wraps targets to customize behaviors like property access, as in new Proxy(target, { get: (target, prop) => Reflect.get(target, prop) * 2 }), which doubles retrieved values. The Reflect API complements Proxies by providing methods to invoke default operations, such as Reflect.set(target, prop, value), enabling transparent forwarding in meta-level code. These features allow procedural code to dynamically alter program behavior at runtime.[123]
Delegative inheritance in JavaScript favors composition over classical inheritance, using prototypes for delegation where objects forward unresolved operations to prototypes.[124] Traits and mixins implement this by composing behaviors into objects without deep hierarchies; for example, a mixin function can apply methods to a class via Object.assign(MyClass.prototype, mixinMethods), enabling reusable traits like logging without extending a base class.[125] Libraries like traits.js resolve conflicts during composition, allowing traits to override or combine methods selectively, promoting flexible, inheritance-light designs.[126] This paradigm aligns with JavaScript's prototype-based model, emphasizing delegation for code reuse.
Advanced Constructs
Modules and Asynchronous Programming
JavaScript supports modular programming through standardized mechanisms that enable code organization, reuse, and dependency management. The ECMAScript 2015 (ES6) specification introduced native modules, allowing developers to export and import bindings using declarativeexport and import statements.[127] These modules are statically analyzable, meaning their structure is determined at compile time, which facilitates optimizations like tree-shaking—dead code elimination that removes unused exports during bundling.[128] For example, a module might export a function as export function greet() { return "Hello"; }, which can then be imported selectively elsewhere with import { greet } from './module.js';, ensuring only referenced code is included in the final bundle.[127]
ECMAScript 2025 extended module support with JSON modules, enabling direct import of JSON files as modules using import attributes to specify the type. For instance, import data from "./config.json" with { type: "json" }; loads the JSON as a module namespace object, avoiding manual parsing and supporting schema validation via additional attributes. This feature simplifies handling configuration files and static data in modular applications.[129]
Prior to ES6 modules, CommonJS served as a de facto standard for modular code, particularly in server-side environments like Node.js, using dynamic require() and module.exports for loading and exporting.[130] This approach, while flexible, lacks static analysis, making it incompatible with tree-shaking and leading to larger bundles compared to ES modules.[131] As of 2025, ES modules have become the preferred format across browsers and Node.js, with CommonJS treated as legacy for new projects.[132]
Asynchronous programming in JavaScript addresses the language's single-threaded, event-driven nature, where operations like I/O or network requests do not block execution via the event loop. Early patterns relied on callbacks, as seen in Node.js-style functions where an asynchronous operation passes results to a provided callback, such as fs.readFile('file.txt', (err, data) => { if (err) return; console.log(data); });.[133] This can lead to nested "callback hell," complicating code readability for complex flows.
The ES2015 specification introduced Promises to manage asynchronous operations more composably, representing a value that may resolve or reject in the future with methods like .then() for fulfillment and .catch() for rejection.[127] For instance, fetch('https://api.example.com/data').then(response => response.[json](/page/JSON)()).catch(error => console.error(error)); chains operations without deep nesting.[134] Building on Promises, ES2017 added async/await syntax, allowing asynchronous code to resemble synchronous code for improved readability; an async function is declared with async function fetchData() { try { const response = await fetch('https://api.example.com/data'); return await response.[json](/page/JSON)(); } catch (error) { console.error(error); } }.[135]
Generators, also from ES2015, enable iterable asynchronous flows by producing sequences of values via function* and yield, which can pause and resume execution, often used in conjunction with Promises for custom async iterators.[127] The Fetch API, standardized by WHATWG, exemplifies Promise-based HTTP requests, providing a modern alternative to XMLHttpRequest with built-in support for requests and responses.[134]
As of ECMAScript 2022, top-level await extends async/await to the module root level, allowing modules to await resources during import without wrapping in an async function, such as const data = await fetch('https://api.example.com/data').then(r => r.json()); export { data };.[136]
Error Handling and Metaprogramming
JavaScript employs exception-based error handling to gracefully manage runtime failures, allowing code to continue execution or recover from issues rather than terminating abruptly. The core mechanism consists of thetry...catch...finally statement, introduced in ECMAScript 3 (ES3), which executes code in a try block and captures any thrown exceptions in a catch block for processing, while the optional finally block ensures cleanup regardless of outcome.[137] The throw statement enables explicit error generation, typically by throwing an instance of the built-in Error constructor or its subclasses, providing a message property for details and a name for the error type.
Built-in error types derive from the Error prototype and cover common failure scenarios. SyntaxError arises during code parsing when syntax is invalid, such as mismatched brackets or reserved word misuse. TypeError signals operations on incompatible types, like calling a non-function or adding incompatible values. ReferenceError occurs when accessing undeclared variables, while RangeError indicates numeric values exceeding safe limits, such as excessive recursion depth. URIError is thrown by URI-handling functions like decodeURI with malformed input, and EvalError—largely legacy—relates to dynamic evaluation failures, though modern engines rarely use it distinctly.[138][139]
For debugging, JavaScript offers lightweight tools integrated into runtime environments. The console.log method, part of the Console API in browsers and Node.js, outputs values to a developer console for inspection during execution, aiding in tracing variable states without halting code. The debugger statement, standardized in ES5, acts as a programmatic breakpoint, invoking the debugger if available in the host environment like browser DevTools, otherwise behaving as a no-op.[140] Modern engines, such as V8 in Chrome and SpiderMonkey in Firefox, automatically generate stack traces—sequences of function calls leading to the error—accessible via the non-standard stack property on Error instances, enhancing post-mortem analysis.
Metaprogramming in JavaScript involves techniques to manipulate code or objects at runtime, enabling dynamic behavior customization. The eval function, present since early ECMAScript editions, evaluates strings as code in the current context, allowing runtime code generation but discouraged due to security vulnerabilities (e.g., code injection) and performance overhead from parsing.
ECMAScript 6 (ES6) introduced Proxy objects, which wrap targets to intercept fundamental operations like property access (get), assignment (set), or function calls (apply), facilitating patterns such as data validation, logging, or virtualization without altering the original object. Complementing Proxy, the Reflect API exposes static methods mirroring these operations (e.g., Reflect.get, Reflect.set), ensuring consistent default behavior and avoiding direct this binding issues in handlers. Together, they enable advanced metaprogramming, such as creating transparent object proxies for debugging or reactive systems.
ES6 also added Symbol, a primitive type for creating unique, immutable keys that avoid property name collisions in objects, ideal for internal or library-specific attributes. Symbols can be global via Symbol.for or unique via Symbol(), with well-known symbols like Symbol.iterator (for iterable protocol) or Symbol.toStringTag (for custom type tagging) serving as standardized hooks to override built-in behaviors, such as iteration or string coercion.[141]
By ECMAScript 2022 (ES2022), class syntax evolved to support private elements using the # prefix, allowing private fields, methods, and accessors accessible only within the class body, promoting encapsulation and preventing external interference—extending metaprogramming by hiding implementation details without conventions like closures or WeakMaps. For instance:
class Example {
#privateField = 42;
#privateMethod() {
return this.#privateField * 2;
}
publicMethod() {
return this.#privateMethod();
}
}
class Example {
#privateField = 42;
#privateMethod() {
return this.#privateField * 2;
}
publicMethod() {
return this.#privateMethod();
}
}
.catch(), mirroring synchronous exception flow.
Security
Vulnerabilities in Web Contexts
JavaScript, as a client-side scripting language executed in web browsers, introduces several security vulnerabilities when handling untrusted data or interacting with web APIs. These risks stem from its dynamic nature and integration with the Document Object Model (DOM), allowing malicious code to execute within the context of a user's session. Primary concerns include injection attacks that bypass browser security models like the same-origin policy.[142] Cross-site scripting (XSS) represents one of the most prevalent vulnerabilities in JavaScript-enabled web applications, where attackers inject malicious scripts into content delivered to users. This occurs when unsanitized user inputs from sources like URL parameters, form fields, or HTTP headers are directly incorporated into HTML or JavaScript output without proper validation. The injected code runs in the victim's browser with the same privileges as legitimate scripts, potentially stealing session cookies, keystrokes, or sensitive data.[143][142] XSS manifests in three main types, each exploiting different injection points in web contexts. Reflected XSS involves immediate reflection of malicious input in a server's response, such as embedding a script tag in a search query URL likehttps://example.com/search?q=<script>alert('XSS')</script>, which the browser executes upon rendering. Stored XSS persists the malicious script on the server, for instance, in a database via user comments on a forum, affecting all users who view the page. DOM-based XSS arises purely on the client side when JavaScript processes untrusted data, such as location.hash, and modifies the DOM unsafely, like using document.write(location.hash) to inject executable code.[144][145]
Cross-site request forgery (CSRF) exploits JavaScript's ability to make authenticated requests, tricking users into performing unintended actions on trusted sites. Attackers craft malicious pages that automatically submit requests using the victim's existing session cookies, which browsers include by default in cross-origin requests for methods like GET or POST. For example, an attacker could embed an image tag <img src="https://bank.com/transfer?amount=1000&to=attacker"> or use JavaScript to fire an XMLHttpRequest, forcing a fund transfer without user awareness. This vulnerability relies on sites failing to verify request origins, amplifying risks in single-page applications where JavaScript handles dynamic updates.[146]
Prototype pollution attacks target JavaScript's prototype-based inheritance, where objects share a common prototype chain, allowing modifications to propagate unexpectedly across the application. An attacker injects properties via sources like query strings (e.g., ?__proto__[polluted]=malicious) or parsed JSON, altering global prototypes like Object.prototype. In web contexts, this can lead to logic bypasses or DOM manipulations, such as setting a polluted property that influences script evaluation and enables arbitrary code execution. Client-side gadgets, like unsafe uses of prototype properties in DOM sinks, exacerbate the issue in browser environments.[147][148]
Timing attacks on cryptographic APIs, including the Web Crypto API, leverage variations in execution time to infer sensitive information from JavaScript operations. These side-channel attacks analyze delays in functions like key comparisons or encryptions, potentially revealing plaintext or keys when implementations are not constant-time. In browser contexts, attackers can measure response times via JavaScript timers, exploiting non-uniform operations in crypto primitives to brute-force secrets.[149]
Supply-chain attacks via the npm registry have historically compromised JavaScript ecosystems, with a notable 2025 incident involving the "Shai-Hulud" worm affecting over 500 packages with millions of downloads and millions of sites. Attackers phished maintainer accounts to inject malware, exfiltrating credentials and self-propagating through dependencies, enabling remote code execution in web applications that include tainted libraries. This event highlighted risks in client-side code loading from unverified third-party modules.[150][151]
Mitigation Strategies
To mitigate security risks in JavaScript applications, particularly those running in web contexts, developers should prioritize input sanitization techniques to prevent injection attacks such as cross-site scripting (XSS). One widely adopted library for this purpose is DOMPurify, a DOM-based sanitizer that removes malicious code from HTML, MathML, and SVG inputs while preserving safe content.[152] DOMPurify operates by parsing and purifying untrusted data before insertion into the DOM, effectively neutralizing XSS payloads without altering the intended structure.[152] Complementing client-side sanitization, server-side enforcement of Content Security Policy (CSP) headers restricts the execution of unauthorized scripts by defining allowed sources for inline code, external scripts, and other resources.[153] CSP directives likescript-src 'self' limit script loading to the same origin, providing a robust defense layer that blocks even sanitized but malicious content from executing.[154]
Secure coding practices form the foundation of JavaScript application safety, emphasizing avoidance of dangerous functions and proper protocol usage. The eval() function, which dynamically executes strings as code, should be entirely avoided as it can lead to arbitrary code execution from untrusted inputs; instead, safer alternatives like JSON.parse() for data deserialization or structured code execution via functions and objects are recommended.[155] All API communications must use HTTPS to encrypt data in transit, preventing man-in-the-middle attacks that could intercept or tamper with JavaScript-loaded resources. Similarly, Cross-Origin Resource Sharing (CORS) must be implemented with precision on servers, using specific origin whitelisting (e.g., Access-Control-Allow-Origin: [https](/page/HTTPS)://trusted.example.com) rather than wildcard policies, to control cross-origin requests initiated by JavaScript's fetch() or XMLHttpRequest.[156]
Development tools play a crucial role in proactively identifying and addressing security issues in JavaScript codebases. Linters such as ESLint, when extended with security-focused plugins like eslint-plugin-security, can detect patterns indicative of vulnerabilities, such as unsafe regular expressions or potential prototype pollution, enforcing rules during development and CI/CD pipelines.[157] For dependency management, static analysis tools like Snyk scan npm packages and lockfiles for known vulnerabilities, providing automated fixes or upgrade paths to patch issues in third-party libraries used by JavaScript applications.[158] These tools integrate seamlessly with workflows, offering vulnerability prioritization based on exploitability and impact.
Browser-native features further enhance JavaScript security by isolating and verifying resources. The sandbox attribute on <iframe> elements creates a restricted environment for embedded content, disabling features like script execution, form submissions, or navigation unless explicitly allowed (e.g., sandbox="allow-scripts allow-same-origin"), thereby containing potential malicious JavaScript within isolated contexts. Subresource Integrity (SRI) ensures the integrity of loaded scripts and stylesheets by requiring cryptographic hashes in the integrity attribute (e.g., <script src="app.js" integrity="sha256-abc123...">), prompting browsers to reject tampered resources from CDNs or external sources.[159] Major browsers enforce CSP with features including automatic reporting of violations via the report-to directive, reducing reliance on external configurations for core protections.[153]
Development Tools
Editors and Debuggers
Visual Studio Code (VS Code) serves as one of the most widely adopted integrated development environments (IDEs) for JavaScript development, offering built-in support for IntelliSense, which provides intelligent code completion, parameter information, and quick info to enhance coding efficiency.[160] This feature extends to refactoring, code navigation, and formatting, allowing developers to manage large JavaScript projects through configurations like jsconfig.json for improved type checking and error detection.[160] Extensions further augment VS Code's capabilities, enabling seamless integration with JavaScript frameworks and runtimes. WebStorm, developed by JetBrains, provides advanced refactoring tools tailored for JavaScript, such as safe renaming of variables, functions, and files across the entire codebase without altering application behavior.[161] It supports extracting methods, introducing variables, and modernizing code practices, like converting functions to classes, which help maintain clean and maintainable JavaScript structures in complex applications.[161] WebStorm's navigation and search features, including symbol renaming and usage analysis, facilitate efficient editing in web, mobile, and desktop JavaScript projects.[162] For browser-based JavaScript debugging, Chrome DevTools offers a comprehensive suite of tools, including line-of-code breakpoints to pause execution at specific points and inspect variables.[163] The console enables logging messages, running arbitrary JavaScript, and profiling performance to identify bottlenecks, while the network panel allows inspection of resource loading, timings, and HTTP requests during web application execution.[164] These features support debugging workflows for client-side code, with source maps enabling inspection of original, unminified files even in production environments.[165] In Node.js environments, the built-in inspector provides a V8-based debugging interface accessible via thenode inspect command, allowing step-through execution, breakpoint setting, and variable inspection in server-side JavaScript applications.[166] VS Code integrates directly with this inspector through its Node.js debugging extension, supporting launch configurations for attaching to running processes, remote debugging, and automatic source map handling for TypeScript or bundled code.[167]
As of 2025, trends in JavaScript development tools emphasize AI-assisted debugging, with GitHub Copilot integrating into IDEs like VS Code to suggest fixes for errors, analyze code issues in real-time, and streamline troubleshooting within the editor.[168] Additionally, AI-powered editors like Cursor, which integrates advanced AI features directly into a VS Code-like interface, have seen rapid adoption among developers.[59] Platforms like Replit facilitate real-time collaboration through multiplayer editing, live cursors, and shared debugging sessions for JavaScript projects, enabling teams to co-develop and iterate without local setup.[169]
Build Tools and Testing
Build tools in JavaScript development encompass bundlers and transpilers that streamline the process of packaging and transforming code for production deployment. Bundlers like Webpack resolve dependencies across modules and generate optimized bundles suitable for browser execution by analyzing import statements and combining assets into cohesive files.[170] Webpack's configuration allows for loaders to process non-JavaScript files, such as CSS or images, ensuring comprehensive asset management during the build phase.[171] Another prominent bundler, Vite, leverages native ES modules in modern browsers to provide a fast development server with near-instantaneous hot module replacement, reducing startup times compared to traditional bundling approaches.[172] Vite's build process employs Rollup for final optimization, balancing speed in development with efficient production outputs.[173] Transpilers enable compatibility with older environments by converting contemporary JavaScript syntax to earlier standards. Babel serves as a primary transpiler, transforming ECMAScript 2015+ features, including arrow functions and classes, into ES5-compatible code through configurable plugins and presets.[174] This allows developers to adopt cutting-edge language features without sacrificing support for legacy browsers.[174] Complementing Babel, the TypeScript compiler (tsc) not only transpiles TypeScript—a superset of JavaScript with static typing—into plain JavaScript but also performs type checking to catch errors at compile time, enhancing code reliability in large-scale applications.[175] TypeScript's output can target various ECMAScript versions, making it versatile for both browser and Node.js environments.[176] Testing frameworks verify code correctness across unit and integration levels, integrating seamlessly with build pipelines. Jest, a zero-configuration testing library, facilitates unit testing by providing snapshot testing, mocking capabilities, and an intuitive API for asserting expected behaviors in JavaScript functions.[177] For instance, developers can write assertions likeexpect(sum(1, 2)).toBe(3); to validate arithmetic logic, with Jest's watch mode enabling rapid iteration during development.[178] For end-to-end testing, Cypress automates browser interactions, simulating user workflows such as form submissions or navigation, while offering real-time reloading and detailed debugging videos.[179] Cypress runs tests directly in the browser, avoiding the flakiness of asynchronous waits common in other tools.
As of 2025, continuous integration and deployment (CI/CD) workflows increasingly incorporate these tools for automated verification. GitHub Actions, when integrated with Playwright, enables cross-browser testing across Chromium, Firefox, and WebKit by executing end-to-end tests in parallel on virtual environments, ensuring compatibility without manual intervention.[180] This setup triggers builds on code pushes, bundling with Webpack or Vite, transpiling via Babel or TypeScript, and running Jest or Cypress suites, thereby maintaining code quality in collaborative projects.[180]
Related Technologies
ECMAScript Derivatives
ECMAScript derivatives extend or subset the core JavaScript language defined by the ECMAScript standard, adapting it for specific use cases such as multimedia, data serialization, or enhanced type safety while maintaining compatibility with JavaScript runtimes. ActionScript, developed by Adobe (originally Macromedia), is an object-oriented programming language derived from ECMAScript, primarily used for scripting interactive content in the Flash platform. It introduced class-based OOP features like inheritance and encapsulation ahead of similar additions in later ECMAScript editions, building on ECMAScript 3 for versions 1.0 and 2.0, and incorporating elements of the ECMAScript 4 draft in version 3.0 released in 2006.[181][182] ActionScript enabled developers to create complex animations and applications within Flash, but following Adobe's end-of-life announcement for Flash Player on December 31, 2020, official support for ActionScript has been deprecated, with content migration encouraged to HTML5 and Web technologies.[183] JSON (JavaScript Object Notation) serves as a lightweight data-interchange format and is a strict subset of JavaScript's object literal syntax, limited to objects, arrays, strings, numbers, booleans, and null values to ensure language-independent serialization.[184][185] This design facilitates easy parsing and generation across programming languages, avoiding executable code like functions or statements. Native support was added in ECMAScript 5 (2009) through the global JSON object, providing methods such asJSON.parse() for deserializing strings into objects and JSON.stringify() for the reverse, standardizing data exchange in web APIs and configurations.[186]
TypeScript, introduced by Microsoft in 2012 as an open-source project, is a typed superset of JavaScript that compiles to plain JavaScript, adding optional static typing to improve scalability for large applications.[187][176] It includes advanced features like interfaces for defining object shapes and contracts, generics for reusable type-safe components (e.g., function identity<T>(arg: T): T), and enums, modules, and decorators, all transpiled to ECMAScript-compatible code without runtime overhead.[188][189] By 2024, TypeScript had achieved widespread adoption, with 67% of developers reporting they write more TypeScript than JavaScript code.[190]
Flow, released by Facebook in 2014, is a static type checker for JavaScript that infers types and annotates code to catch errors at development time without requiring a full language superset or compilation step.[191][192] It supports gradual typing, allowing optional annotations alongside inferred types for properties, functions, and unions, and integrates seamlessly with existing JavaScript codebases. Despite its focus on performance for large-scale projects like React, Flow has seen less adoption than TypeScript as of 2024, with TypeScript dominating type-checking usage in developer surveys.[190]
Complementary Languages and Formats
WebAssembly (Wasm) serves as a complementary binary instruction format that enables high-performance code execution alongside JavaScript in web browsers. Designed as a portable compilation target for various programming languages, Wasm modules can be loaded and invoked directly from JavaScript, allowing developers to offload compute-intensive tasks such as game engines, image processing, or scientific simulations to more efficient bytecode while leveraging JavaScript for user interface logic. The format was first standardized and released by the World Wide Web Consortium (W3C) in 2017, with initial browser support from major vendors like Mozilla, Google, and Microsoft.[193] CoffeeScript emerged as a transpiler-based language that compiles to readable JavaScript, offering a more concise and expressive syntax inspired by languages like Ruby and Python to address perceived verbosity in early JavaScript. Introduced by Jeremy Ashkenas in December 2009, it eliminates semicolons, uses significant whitespace for indentation, and provides features like list comprehensions and pattern matching, which were later incorporated into ECMAScript 6 (ES6) in 2015. Although its adoption has declined significantly since ES6's native support for similar constructs, CoffeeScript remains maintained, with its latest version (2.7.0) released in 2022, and is still used in legacy projects for its simplicity in generating clean JavaScript output.[194] Dart, developed by Google, functions as an alternative client-optimized programming language for web and mobile development, compiling to JavaScript for browser execution or to native code for other platforms. Released in 2011, Dart features a C-style syntax with strong typing, null safety, and asynchronous programming support via async/await, making it suitable for building high-performance applications without direct JavaScript dependency. It powers the Flutter framework, which enables cross-platform UI development for web, mobile, and desktop, with Dart-to-JavaScript compilation ensuring seamless integration into existing web ecosystems as of 2025.[195] Other languages provide browser execution through JavaScript interop or compilation, expanding options beyond native JavaScript. Brython implements Python 3 directly in the browser by translating Python code to JavaScript at runtime, allowing developers to use Python's ecosystem for client-side scripting while interacting with the DOM via a Pythonic API; it supports standard Python libraries and is actively developed for educational and prototyping use cases. Rust integrates with WebAssembly to deliver safe, high-performance modules callable from JavaScript, leveraging Rust's memory safety and concurrency features for tasks like cryptography or real-time simulations, with tools like wasm-bindgen facilitating bidirectional communication. As of 2025, Blazor from Microsoft enables C# code to run in browsers via WebAssembly, supporting full .NET runtime execution for interactive web UIs without JavaScript, and is positioned as a primary investment for .NET web development.[196][197][198]References
- https://wiki.commonjs.org/wiki/Modules/1.1
