首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

JavaScript函數調用與函數表達式賦值的本質區別解析

     編輯:程式設計疑難解答

代碼對比


// 情況 1:函數調用 + 賦值
function aa() { alert("123"); }
var bb = aa();  // ① 執行 aa() → alert("123") → 返回 undefined → bb = undefined

// 情況 2:函數表達式賦值
var bb = function() { alert("123"); }; // ② 創建匿名函數對象 → 賦值給 bb → 不執行
// 後續調用:bb(); // 才會 alert

本質區別

維度情況 1: `var bb = aa()`情況 2: `var bb = function(){}`
操作類型函數調用表達式函數表達式 (賦值)
執行時機**立即執行** `aa()`**延遲執行**,賦值時不執行
結果值函數 `aa` 的**返回值** (`undefined`)**函數對象本身** (可調用)
bb 類型`undefined` (或返回值類型)`Function`
副作用函數體內代碼立即運行 (alert、副作用)無副作用,僅創建閉包/對象

內存/引擎視角

// 情況 1
1. 解析 aa 函數聲明 → 創建 Function 對象 → 掛載 window.aa
2. 執行 aa() → 壓棧執行上下文 → alert → 彈棧 → 返回 undefined
3. 變量 bb = undefined

// 情況 2
1. 解析 function(){} → 創建 Function 對象 (匿名)
2. 變量 bb = 該 Function 對象引用
3. 結束,函數體未執行

常見應用場景

1. 立即執行函數表達式 (IIFE) - 情況 1 變體

(function() { 
    var private = 'secret'; 
    window.myModule = { get: () => private };
})(); // 立即執行,創建私有作用域

2. 回調函數傳遞 - 情況 2

setTimeout(function() { console.log('later'); }, 1000); // 傳遞函數對象,稍後調用
btn.addEventListener('click', handleClick); // 傳遞引用,非調用
// ❌ btn.addEventListener('click', handleClick()); // 錯誤:立即執行,傳入 undefined

3. 高階函數返回函數 - 情況 2

function createMultiplier(factor) {
    return function(x) { return x * factor; }; // 返回函數對象 (閉包)
}
var double = createMultiplier(2);
double(5); // 10

避坑指南

錯誤代碼現象修正
`var x = func();` 期望獲取函數x 為返回值`var x = func;` (不加括號)
`setTimeout(doSomething(), 1000)`立即執行`setTimeout(doSomething, 1000)`
`arr.map(item.process())`立即執行 process`arr.map(item => item.process())` 或 `arr.map(item => item.process)`

總結

**括號 `()` 是調用運算符**,會立即執行函數體並產生返回值。**無括號只是引用**,傳遞函數對象本身。這是 JavaScript「函數是一等公民」的核心體現:**函數可作為值傳遞、賦值、返回**,只有加 `()` 才觸發執行。牢記:**傳回調用用引用,需要結果才加括號**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved