在非严格模式下,IIFE中的this指向全局对象,根本原因是函数独立调用时触发默认绑定规则;严格模式下则为undefined;外层括号仅为分组操作符,不创建上下文;可通过call/apply/bind或箭头函数等方式手动干预。
在非严格模式下,IIFE 中的 this 指向全局对象(如浏览器中的 window),根本原因在于函数调用时的默认绑定规则——当函数独立调用、没有明确上下文时,this 自动绑定到全局对象。这和 IIFE 的“立即执行”形式无关,而是 JavaScript 执行上下文建立时的底层机制。
默认绑定发生在函数以“简单调用”形式出现时,即:
– 不是作为对象方法(obj.fn())
– 不是通过 call/apply/bind 显式绑定
– 不是作为构造函数(new fn())
– 也不是箭头函数(它不绑定 this,而是继承外层)
此时,JavaScript 引擎会把 this 设为全局对象(非严格模式)或 undefined(严格模式)。
IIFE 写成这样:
(() => { console.log(this); })();虽然它被包裹在括号里,但执行时仍是“直接调用”——没有点号、没有 call、没有 new。所以触发默认绑定。
有人误以为 (function(){...})() 中的括号“属于”函数自身,从而产生上下文。但语法上,外层括号只是**分组操作符**,用于消除函数声明与调用之间的歧义,并不创建调用上下文。
等价于:
const f = function(){ console.log(this); };只是 IIFE 把定义和调用压缩在一行,本质未变。
开启严格模式后,默认绑定不再兜底到全局对象:
(function(){ "use strict"; console.log(this); })(); // undefined这反而印证了原理:默认绑定是一条明确规则,而非“总是指向 window”。它的行为由是否处于严格模式决定。
默认绑定可被更高优先级的绑定方式覆盖:
(function(){ console.log(this); }).call({x:1}); → 输出 {x:1}
this,而是沿作用域链查找外层的 this(可能来自外层普通函数)obj = { f: function(){ console.log(this); } }; obj.f();
注意:这些都不是“IIFE 自身改变了 this”,而是你绕过了默认绑定。