前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库箭头函数 IIFE 与普通函数区别
JavaScript函数与作用域

箭头函数写的 IIFE 和普通函数写的 IIFE 有什么区别?

隔离变量这件事上两者没区别,函数体都是独立作用域。区别在于箭头函数没有自己的 this 和 arguments,IIFE 里读到的是外层函数的;普通函数 IIFE 被直接调用,严格模式下 this 是 undefined,arguments 是它自己的。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#函数与作用域
先看核心答案读代码示例
理解线索

立即执行不改变函数本身的规则

  1. 箭头 IIFE不创建 this 和 arguments,沿作用域链用外层函数的
  2. 普通函数 IIFE每次调用有自己的 this 和 arguments,this 由调用方式决定
  3. 共同点函数体都是新作用域,内部声明的变量不会漏到外面

在对象方法里写 IIFE,需要用方法的 this 时箭头版本最省事;换成普通函数就得手动 .call(this) 或者提前存一个 self。

核心回答

先记住这个答案

两种 IIFE 都是「定义完立刻调用」,函数体都是独立作用域,所以隔离变量的效果完全一样。区别不在 IIFE 这个写法,而在函数种类:箭头函数没有自己的 this 和 arguments,在 IIFE 里读到的是外层函数的;普通函数 IIFE 是一次普通调用,严格模式下 this 是 undefined,非严格模式下是全局对象,arguments 是这次调用自己的。所以只要 IIFE 内部用到了 this 或 arguments,两种写法的结果就会不一样。

  • 两种写法隔离变量的效果一样
  • 箭头 IIFE 里的 this、arguments 来自外层
  • 普通 IIFE 直接调用,严格模式下 this 是 undefined
  • 箭头 IIFE 的括号只能包住函数,不能包到调用后面

在对象方法里对比两种 IIFE

最能看出差别的场景是在对象方法里写 IIFE,因为外层有一个明确的 this 和 arguments。

同一个方法里分别用两种 IIFEJavaScript
'use strict'
const user = {
  name: 'Ada',
  greet() {
    const fromArrow = (() => this.name)() // 用的是 greet 的 this
    const fromFunction = (function () {
      return this // 普通调用,严格模式下是 undefined
    })()
    console.log(fromArrow, fromFunction)

    ;(() => console.log(arguments[0]))('arrow-arg') // 读的是 greet 的 arguments
    ;(function () {
      console.log(arguments[0]) // 读的是自己的 arguments
    })('function-arg')
  }
}
user.greet('greet-arg')
查看输出与解释
Ada undefined
greet-arg
function-arg

箭头 IIFE 读 this.name 拿到 'Ada',因为它没有自己的 this,往外找到了 greet 的 this,也就是 user。普通函数 IIFE 是被直接调用的,前面没有对象,严格模式下 this 就是 undefined。 arguments 同理。箭头 IIFE 明明传了 'arrow-arg',打印出来却是 'greet-arg',因为它读的是外层 greet 的 arguments,自己传进去的参数被忽略了。普通函数 IIFE 读到的是自己收到的 'function-arg'。

普通函数 IIFE 想用外层 this 怎么办
在 ES6 之前,常见做法是在外面先写 var self = this,IIFE 里用 self。也可以写成 (function () { ... }).call(this),把外层的 this 显式传进去。有了箭头函数以后,这两种写法基本都可以省掉。 反过来,箭头 IIFE 没办法换 this。对箭头函数调用 .call(obj) 不会报错,但传进去的 obj 会被忽略,this 还是外层的。

写法上的两个细节

普通函数 IIFE 的括号位置比较随意,(function () {})() 和 (function () {}()) 都能跑。箭头函数不行,只能写成 (() => {})(),把括号包到调用后面的 (() => {}()) 是语法错误,因为箭头函数体后面不能直接接调用。

另一个细节是 async 版本。(async () => { await init() })() 是现在最常见的 IIFE 写法之一,用来在不支持顶层 await 的地方开一个异步入口。写成普通函数 (async function () { ... })() 也可以,区别仍然只在 this 和 arguments。不管哪种,返回的都是 Promise,记得用 .catch() 处理错误。

回答前,多想一步

容易答错的地方

以为箭头 IIFE 执行时会得到一个新的 this
箭头函数任何时候都不创建 this,立即执行也一样。它的 this 在定义时就由外层决定了。
以为普通函数 IIFE 的 this 会是外层对象
IIFE 写在对象方法里,不等于它被这个对象调用。它是直接调用的,前面没有 obj.,所以 this 走默认规则,和写在哪个方法里无关。
试着用自己的话回答

面试官还会怎么问?

箭头 IIFE 能被 new 调用吗?

不能。箭头函数没有 prototype,也不能作为构造函数,写 new (() => {})() 会抛 TypeError。普通函数 IIFE 理论上可以 new,但实际没人这么用。

箭头函数里想拿到所有参数怎么办?

用剩余参数,写成 ((...args) => console.log(args))(1, 2)。args 是真正的数组,比 arguments 更好用,这也是新代码基本不再用 arguments 的原因。

顶层代码里的两种 IIFE,this 有区别吗?

在 ES 模块顶层,外层 this 是 undefined,箭头 IIFE 读到 undefined;普通函数 IIFE 在模块里默认是严格模式,也是 undefined,结果一样。在非严格的浏览器脚本里就不同了:箭头 IIFE 读到的是顶层的 window,普通函数 IIFE 被直接调用,this 也会回退成 window,结果碰巧相同,但原因不一样。

从一道题,走向一组知识

把知识连起来

函数与作用域

函数的 length 是什么?加了默认参数和剩余参数后会变吗?

箭头函数和普通函数的 length 计算规则一样,函数种类影响的是 this 和 arguments,不影响参数元数据。

函数与作用域

什么是词法作用域?作用域链是怎么形成的?

箭头函数的 this 和普通变量一样沿词法作用域向外找,看懂作用域链就能看懂箭头 IIFE。

参考资料

  • Arrow function expressions - MDN

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 在对象方法里对比两种 IIFE
  3. 写法上的两个细节
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑