Learn all about the JavaScript 'void'

Learn all about the JavaScript 'void'

JavaScript is a language notorious for its quirks and oddities. Among these, the often-seen javascript:void 0 expression stands out as both cryptic and misunderstood. You've likely encountered it in old-school anchor tags—<a href="javascript:void 0">Click me</a>—and wondered: What does it do? Why not simply use # or javascript:;? Is it still relevant, or merely a relic of the past? In this in-depth exploration, we'll demystify the void operator in JavaScript, trace its history, dissect the specific use of void 0, examine modern best practices, and illuminate when (if ever) you might still reach for it today.

Table of Contents

  1. The JavaScript void Operator: Basics
  2. Why void 0? The Rationale Behind the Expression
  3. Common Use Cases and Historical Context
  4. Comparing Alternatives: #, javascript:;, and More
  5. Browser Quirks and Cross-Compatibility
  6. Performance Implications
  7. Modern JavaScript & Framework Considerations
  8. When to Use—and When to Avoid—javascript:void 0
  9. Conclusion: Legacy vs. Best Practice

1. The JavaScript void Operator: Basics

At its core, JavaScript's void operator evaluates an expression and then returns undefined—no matter what the expression's value might be. Its syntax is straightforward:

void expression
  • Evaluation: The operand (the expression) is evaluated first.
  • Result: The final result of the operation is always undefined.
console.log(void 42);          // logs: undefined
console.log(void "hello");     // logs: undefined
console.log(void (a = 5 + 7)); // logs: undefined

Under the hood, void exists primarily to produce an unambiguous undefined, especially in contexts where one doesn't want any value. Before ES5 standardized undefined as a non-writable, non-configurable global, using void was one foolproof way to guarantee an immutable undefined return, impervious to tampering:

undefined = "foo";
console.log(undefined);        // might log "foo" in old engines
console.log(void 0);           // reliably logs: undefined
Key takeaway: void forces its operand to be evaluated (for side effects) and then discards any result, yielding undefined.

2. Why void 0? The Rationale Behind the Expression

Arguably the most common usage pattern is void 0. Why not simply write void or void 1?

  1. void Needs an Operand. Unlike some unary operators, void cannot stand alone; it must operate on something.
  2. Choosing 0 vs. Other Values. 0 (zero) is the smallest, simplest numeric literal—cheap to parse and non-computationally expensive. Whether you wrote void 42 or void (2+2), the result is the same: undefined. But void 0 became the conventional choice for brevity and clarity.
  3. Guaranteed undefined. Historically, if one could not trust the global undefined (pre-ES5), void 0 was the safest bet. It required no external variables or reserved words—just the operator and a literal.

Thus, void 0 emerged as a succinct idiom.

3. Common Use Cases and Historical Context

3.1 Inline JavaScript in Links

Before the era of unobtrusive JavaScript and event listeners, developers often embedded code directly into href attributes of anchors:

<a href="javascript:void 0" onclick="doSomething();">Click me</a>
  • Goal: Prevent the browser from navigating away from the current page (the default behavior of <a> tags).
  • Alternative: Developers sometimes used href="#", but this navigates to the top of the page (adds an entry to the browser's history stack) and alters the URL hash.

3.2 Bookmarklets

Bookmarklets—tiny JavaScript snippets saved as bookmarks—often start with javascript:. Using void 0 at the end prevents the bookmarklet from replacing the current page with the return value of the script:

javascript:(function(){
  /* do stuff */
})(),void 0

3.3 Preventing Default Behavior

In modern code, event.preventDefault() is the standard approach to cancel default link behavior. But in older scripts (or minimal inline contexts), return false or void 0 were sometimes used interchangeably:

<a href="javascript:void 0" onclick="return handleClick();">Click</a>

4. Comparing Alternatives: #, javascript:;, and More

Approach Behavior Pros Cons
href="#" Navigates to top of page, alters URL hash Simple Modifies URL/hash, scrolls to top
href="javascript:void 0" No navigation, no hash modification Keeps page static Inline JS discouraged
href="javascript:;" Equivalent to void 0 since ; yields undefined No page navigation Semicolon is less self-documenting
<button type="button">…</button> Semantically a button, no navigation by default Semantic HTML, accessible Requires styling to look like a link if needed
<a href="#" onclick="…">…</a> + JS Prevents default link navigation and runs custom code Direct control over behavior Must explicitly call preventDefault(), more verbose

Why javascript:; works: A lone semicolon is an empty statement. Evaluated as an expression, it yields undefined, akin to void 0. But since ; can look odd, 0 is clearer to most readers.

5. Browser Quirks and Cross-Compatibility

Modern browsers uniformly implement void and handle javascript: URIs in the same manner. However, subtle differences existed in older browsers (IE6–IE8):

  • History Stack: href="#" adds entries even if the hash is unchanged; many users complained that the back button misbehaved.
  • javascript: schemes: Certain CSP (Content Security Policy) configurations can block inline scripts or javascript: URIs entirely for security reasons.
  • Accessibility Concerns: Screen readers may announce "link" but not communicate that it does "nothing"; semantically, a <button> is more appropriate if the intent is purely an action, not navigation.

6. Performance Implications

Using void 0 in an href has negligible performance overhead. The browser:

  1. Parses the javascript: URI.
  2. Executes the operand (void 0).
  3. Receives undefined.
  4. Discards any navigation attempt (since return value is not a string URL).

While parsing inline JavaScript is marginally slower than a simple href="#", the difference is imperceptible in real-world usage. More critical is the cost of page reflow or hash change animations—void 0 avoids these.

7. Modern JavaScript & Framework Considerations

Unobtrusive JavaScript: In frameworks (React, Vue, Angular), you typically bind event handlers rather than embedding javascript: URIs:

function MyLink() {
  return (
    <a href="#" onClick={e => { e.preventDefault(); doSomething(); }}>
      Click me
    </a>
  );
}

Accessibility & Semantics: When an element purely triggers logic (and doesn't navigate), a <button> is semantically correct:

<button type="button" onClick={doSomething}>
  Do Something
</button>

Linting & Best Practices: ESLint rules (e.g., jsx-a11y/anchor-is-valid) will flag href="javascript:void 0" as invalid. Modern tooling encourages:

  • Using <button> for actions.
  • If an <a> must be used (for styling), include href="#" but always call e.preventDefault() in JS.

8. When to Use—and When to Avoid—javascript:void 0

Use Cases for javascript:void 0

  • Legacy Projects: Maintaining older codebases where refactoring to unobtrusive handlers isn't feasible.
  • Bookmarklets: Ensuring the script doesn't navigate away from the page.
  • Minimal Inline Demos: Quick proof-of-concepts or StackOverflow snippets where brevity is paramount.

When to Avoid It

  • New Development: Favor semantic HTML and unobtrusive event handlers.
  • Accessibility: Avoid confusing screen readers and assistive technologies.
  • Security/CSP: Many Content Security Policies disallow javascript: URIs, making void 0 unusable.
  • Linting Standards: Modern linters will typically error on inline JS.

9. Conclusion: Legacy vs. Best Practice

javascript:void 0 holds a firm place in JavaScript's historical toolkit—an unambiguous way to yield undefined and suppress unwanted navigation. Yet, in today's development environment, its utility is limited:

  • For new code, embrace semantic HTML (<button>), unobtrusive JavaScript (event listeners), and modern accessibility standards.
  • For existing legacy code, understanding void 0 remains crucial for maintenance and debugging.

Ultimately, while javascript:void 0 is a fascinating footnote in the language's evolution, it belongs more to the annals of JavaScript lore than to contemporary best practices. By recognizing its original role and knowing when to replace it, you ensure cleaner, more maintainable, and more accessible code—unleashing the true power of modern JavaScript.

#javascript void 0 #void operator #javascript void #prevent link navigation #inline JavaScript #bookmarklet void 0 #void 0 tutorial #JavaScript quirks #undefined return #legacy JS techniques

Subscribe to our newsletter

12k+

Subscribers

Weekly

Frequency

Free

Always