不重新加载页面能否重复调用已执行的IIFE?
结论
默认写法的IIFE无法二次调用,只要留存了函数引用的IIFE完全可以重复调用,和普通函数调用效果完全一致,不需要刷新页面。
原理说明
IIFE的本质是「定义后立刻执行的函数表达式」,它和普通函数的唯一区别只是多了定义即执行的触发逻辑,能不能重复调用的核心从来不是「它是不是IIFE」,而是你是否在可访问的作用域内持有了对应函数对象的引用。
不同场景的具体表现
- 无引用留存的常规匿名IIFE:无法二次调用
这是最常见的IIFE写法:
这类写法里,匿名函数没有被任何外部变量持有,执行完成后执行上下文出栈,没有外部引用的函数对象会被垃圾回收机制回收,外部作用域根本拿不到这个函数,自然不可能再次调用。(function() { console.log('iife run') // 业务逻辑 })() - 具名IIFE:仅内部可递归,外部无法直接调用
如果你给IIFE写了函数名,这个标识符的作用域仅存在于函数内部,外部是访问不到的:(function namedIIFE() { console.log('iife run') // 函数内部可以拿到namedIIFE引用,支持递归调用 // 比如满足特定条件时写 namedIIFE() 是合法的 })() // 外部直接调用 namedIIFE() 会抛出引用错误 - 留存了引用的IIFE:支持任意次重复调用,和普通函数无差异
如果你需要IIFE初始化自动执行一次,后续还能手动触发调用,只需要把可执行的函数引用暴露到外部可访问的作用域即可,最常见的写法是利用IIFE返回函数,形成闭包留存私有状态:// IIFE定义后立刻执行,返回的内部函数被赋值给外部变量 const iifeController = (function() { // 这里写的初始化逻辑,页面加载就会执行 let count = 0 console.log('IIFE初始化执行,count初始值为', count) // 返回的函数会被外部变量持有,后续可以随时调用 return function() { count++ console.log('手动调用IIFE逻辑,当前count为', count) } })() // 后续调用和普通函数完全一致,不需要刷新页面 iifeController() // 输出:手动调用IIFE逻辑,当前count为 1 iifeController() // 输出:手动调用IIFE逻辑,当前count为 2
注意点
不要把IIFE的执行返回值和函数本体搞混:如果你的IIFE返回的是基本类型值、普通对象而非函数,那外部变量拿到的是执行结果而非可执行函数,自然没法当函数调用。只要你持有的是合法的函数引用,不管它当初是不是以IIFE形式执行过,都可以随时重复调用。
内容的提问来源于stack exchange,提问作者Ctsa3
相关产品推荐
相关产品推荐

