Welcome!
1004 字
5 分钟
js匿名函数表达式和函数执行
- 是否借助ai
JavaScript 立即执行函数表达式(IIFE)与表达式基础
1. 什么是 IIFE?
-
全称:Immediately Invoked Function Expression(立即调用函数表达式),念作“伊夫”。
-
常见拼写错误:经常被误打成
llfe(注意是字母 I,不是 L)。 -
基本写法:
(function () { // 代码逻辑… })();
2. 核心原理:两对括号的分工
以 (function () { ... })(); 为例,这里有两对作用完全不同的括号:
- 第一对括号
( ... ):分组运算符。- 作用:JS 引擎默认把
function开头的代码当作“函数声明(语句)”,而语句不能匿名。加括号强制将其转换为“函数表达式”。 - 结果:这段代码求值后,结果就是这个函数对象本身。
- 作用:JS 引擎默认把
- 第二对括号
():函数调用运算符。- 作用:在求值得到的“函数对象”后面加上
(),表示立刻执行它。 - 结果:函数内部的代码被执行。
- 作用:在求值得到的“函数对象”后面加上
3. 深入理解:表达式(Expression) vs 语句(Statement)
- 表达式(Expression):一段能算出一个值的代码(如
1 + 2、变量a、function() {})。 - 语句(Statement):下达指令让程序去做一件事,不一定有值(如
var a = 5;、if(){}、function foo(){})。
关键规则:
如果一行代码以 function 开头,JS 会默认认为你在写函数声明(语句)。
在圆括号内部,JS 会强制把里面的东西当成表达式来解析。
function () {} // 报错!JS 认为这是语句,必须给函数起个名字。(function () {}) // 成功!外面的括号让 JS 把它当成“表达式”,算出了一个值(函数本身)。4. 破解疑惑:没有 return,为什么也是表达式?
- 表达式的值 ≠ 函数的返回值。
(function(){ ... })作为一个表达式,它的值是“函数对象本身”(哪怕函数内部没有return,它本身也是一个可以执行的对象)。- 函数内部的
return决定的是“函数被调用后返回什么”,不影响它自身作为表达式求值的结果。 - 只有当表达式的值恰好是一个函数时,后面紧跟
()才会执行。如果是数字1(),会直接报错TypeError。
5. 极简理解法:两步拆解法(推荐)
不要把 (function(){...})() 当成一个整体死记硬背,把它拆成两步:
// 第一步:表达式求值,拿到函数对象var tempFn = (function () { var path = location.pathname.split("/").pop() || "index.html"; // ... 中间省略 ...});// 此时 tempFn 是一个函数,虽然它内部没有 return,但它自己就是一个值。
// 第二步:在函数对象后面加 () 来执行它tempFn();(function(){...})() 只是把这两步合并写在了一起而已。
6. 为什么需要 IIFE?(历史背景与作用)
在 ES6(2015年)发布之前,JavaScript 只有全局作用域和函数作用域,只有 var。
- 避免全局污染:如果不包裹在 IIFE 中,
path、links等变量会变成全局变量,容易引发命名冲突。 - 数据私有化(闭包沙箱):IIFE 创建了独立作用域,外部无法访问内部变量,执行完毕后内部变量被立刻销毁(垃圾回收)。
通俗比喻(自热火锅):
(function() {...})是把火锅组装好。- 最后的
()就是拉下发热包拉环。 - 它自己发热、自己煮熟(自己执行),吃完之后(执行完毕),锅里的东西(内部变量)就扔掉了,不会留在你的厨房(全局作用域)里占地方。
7. 现代开发还需要 IIFE 吗?
- 老代码 / 原生 JS:非常常见(如 jQuery 时代)。
- 现代 ES6 模块化开发:用得少了。因为 ES Module(
export/import)本身就自带模块作用域,不需要 IIFE 来隔离变量。开发者通常会直接写export function initNav() {...},在需要的地方显式调用,代码更清晰可控。
一句话总结:表达式负责“算出一个值(比如函数)”,末尾的
()负责“扣动扳机执行它”。
js匿名函数表达式和函数执行
https://lichangzhuo.xyz/posts/js匿名函数表达式和函数执行/