JS 中 void 關鍵詞的使用解析

在 JavaScript 中,void是一個容易被忽略但功能獨特的一元運算符,核心作用是執行表達式並強制返回 undefined。無論右側表達式的返回值是什麼,void都會 “吞噬” 其結果,僅輸出 undefined。這個特性讓void在處理表達式執行、避免返回值干擾、創建無返回值的鏈接等場景中發揮關鍵作用,尤其在前端開發和函數式編程中,能解決一些特殊的語法和邏輯問題。

一、void 的基礎用法

void的語法非常簡潔:void 表達式 或 void(表達式)(括號僅為優先級處理,兩種寫法效果一致)。核心規則是:先執行右側表達式,再返回 undefined。

1. 基礎執行邏輯
// 執行簡單表達式,返回undefined
console.log(void 123); // 輸出:undefined
console.log(void "hello"); // 輸出:undefined
console.log(void true); // 輸出:undefined

// 執行復雜表達式(運算、函數調用等),仍返回undefined
let num = 10;
console.log(void (num += 5)); // 輸出:undefined
console.log(num); // 輸出:15(表達式已執行,num被修改)

// 執行函數調用,函數返回值被吞噬
function getValue() {
  return "函數返回值";
}
console.log(void getValue()); // 輸出:undefined
console.log(getValue()); // 輸出:函數返回值(對比:無void則返回函數值)
2. 括號的使用場景

當表達式包含運算符(如賦值、邏輯運算)時,建議加括號明確執行範圍,避免語法歧義:

// 無括號:void僅作用於num,賦值運算未執行
void num = 20; // 報錯:Uncaught ReferenceError: Invalid left-hand side in assignment

// 有括號:正確執行賦值表達式
void (num = 20); 
console.log(num); // 輸出:20

// 邏輯表達式加括號
console.log(void (10 > 5 ? "大於" : "小於")); // 輸出:undefined

二、void 的核心應用場景

1. 阻止 a 標籤的默認跳轉行為

這是void最經典的前端應用場景:在<a>標籤的href屬性中使用javascript:void(0),點擊鏈接時執行表達式但不跳轉、不刷新頁面,也不會修改瀏覽器歷史記錄。

<!-- 傳統寫法:href="#"會跳轉到頁面頂部,有滾動副作用 -->
<a rel="nofollow" href="#" onclick="alert('點擊了鏈接')">點我(有滾動)</a>

<!-- 推薦寫法:void(0)阻止默認跳轉,無副作用 -->
<a rel="nofollow" href="javascript:void(0)" onclick="alert('點擊了鏈接')">點我(無滾動)</a>

<!-- 進階:執行復雜邏輯,仍返回undefined -->
<a rel="nofollow" href="javascript:void(console.log('鏈接點擊') || doSomething())">執行邏輯</a>

<script>
function doSomething() {
  console.log("執行自定義邏輯");
}
</script>

對比href="javascript:undefined",void(0)更簡潔且語義明確,是前端開發的通用寫法。

2. 確保函數返回 undefined

某些場景下需要函數強制返回 undefined(即使表達式有返回值),void能精準實現這一需求,避免因返回值意外泄露導致的邏輯錯誤。

// 場景:回調函數需返回undefined,避免影響調用方邏輯
function callback() {
  // 執行核心邏輯
  const result = calculateData();
  // 強制返回undefined,即使result有值
  return void result;
}

function calculateData() {
  return { code: 200, data: [] };
}

console.log(callback()); // 輸出:undefined

// 對比:無void則返回calculateData的結果
function badCallback() {
  return calculateData();
}
console.log(badCallback()); // 輸出:{ code: 200, data: [] }
3. 執行立即調用函數表達式(IIFE)

雖然現代 JS 中 IIFE(立即執行函數)可直接通過(function(){})()實現,但void也能用於執行匿名函數,且無需額外括號(語法更簡潔)。

// 傳統IIFE寫法:需括號包裹函數
(function() {
  console.log("傳統IIFE執行");
})();

// void實現IIFE:無需括號,執行函數並返回undefined
void function() {
  console.log("void IIFE執行");
}();

// 箭頭函數版本
void (() => {
  console.log("箭頭函數IIFE執行");
})();

注意:箭頭函數作為 IIFE 時,仍需括號包裹,否則void會優先作用於箭頭函數語法,導致報錯。

4. 避免表達式返回值干擾鏈式調用

在鏈式調用中,若某一步僅需執行邏輯而無需返回值,void可阻止表達式返回值破壞鏈式結構。

// 場景:數組forEach執行後返回undefined,不影響後續邏輯
const arr = [1,2,3];
const result = arr
  .map(num => num * 2) // 返回新數組
  .filter(num => num > 3) // 返回過濾後的數組
  .forEach(num => void console.log(num)); // 執行打印,返回undefined

console.log(result); // 輸出:undefined(forEach本身返回undefined,void強化這一特性)

// 對比:無void時,console.log返回undefined,結果一致,但void語義更清晰
const badResult = arr.map(num => num * 2).forEach(num => console.log(num));
console.log(badResult); // 輸出:undefined

三、void 的特殊規則與注意事項

1. void 0 等價於 undefined

在早期 JS 中,undefined並非保留字,可能被意外賦值(如undefined = 10),而void 0始終返回真正的 undefined,因此成為獲取 undefined 的 “安全方式”。

// 極端場景:undefined被重賦值
let undefined = "被修改的undefined";
console.log(undefined); // 輸出:被修改的undefined
console.log(void 0); // 輸出:真正的undefined

// 安全判斷值是否為undefined
function isUndefined(value) {
  return value === void 0;
}

console.log(isUndefined("")); // false
console.log(isUndefined(void 0)); // true

現代 JS 中,undefined已被規範為不可寫(嚴格模式下賦值會報錯),但void 0仍作為獲取 undefined 的通用寫法,兼容所有環境。

2. void 不改變表達式的執行邏輯

void僅 “吞噬” 表達式的返回值,不會影響表達式本身的執行(如變量修改、函數調用、DOM 操作等)。

let count = 0;
// 執行count++,返回undefined,但count仍會自增
console.log(void count++); // 輸出:undefined
console.log(count); // 輸出:1

// 執行DOM操作,返回undefined,操作仍生效
void document.body.classList.add("active");
console.log(document.body.classList.contains("active")); // 輸出:true
3. void 不能用於語句(僅能用於表達式)

void的右側必須是 “表達式”(有返回值的代碼),不能是 “語句”(如 if、for、function 聲明等),否則會報錯。

// 錯誤示例:void右側是if語句
void if (true) { console.log("執行if"); } // 報錯:Uncaught SyntaxError: Unexpected token 'if'

// 正確示例:將語句包裹為表達式(IIFE)
void (() => {
  if (true) { console.log("執行if表達式"); }
})(); // 輸出:執行if表達式

四、void 與其他返回 undefined 方式的對比

方式 特點 適用場景
void 表達式 執行表達式 + 強制返回 undefined,最安全 阻止跳轉、強制返回 undefined、IIFE
return undefined 顯式返回,但 undefined 可能被重賦值 函數內明確返回 undefined(現代環境)
return; 無返回值時默認返回 undefined 函數內無需返回值的場景
undefined 簡潔,但早期環境可能被修改 現代環境、非嚴格場景

示例對比:

// 四種返回undefined的方式
function fn1() { return void 0; }
function fn2() { return undefined; }
function fn3() { return; }
function fn4() { void 123; } // 無return,默認返回undefined

console.log(fn1()); // undefined
console.log(fn2()); // undefined
console.log(fn3()); // undefined
console.log(fn4()); // undefined

void作為 JS 中功能專一的運算符,雖然使用場景不如typeof、in廣泛,但在阻止鏈接跳轉、強制返回 undefined、執行 IIFE 等場景中是不可替代的。掌握它的核心規則 ——“執行表達式,返回 undefined”,並結合前端開發的實際需求靈活運用,能解決一些特殊的語法問題,讓代碼更健壯、語義更清晰。