默认绑定取决于函数调用方式而非定义方式:纯函数调用(如foo()、setTimeout(cb,0)、事件回调)且无对象前缀时触发;非严格模式下this指向全局对象,严格模式下为undefined;箭头函数不适用默认绑定。

识别不同执行上下文中的 this 默认绑定规则,关键不在于“函数怎么写”,而在于“函数怎么被调用”。只要抓住调用形式是否带对象前缀、是否启用严格模式、是否处于特殊环境(如事件、定时器、自执行函数),就能快速判断默认绑定的结果。
看调用方式:有没有“点”或对象上下文
默认绑定只发生在纯粹的函数调用场景——也就是没有通过 .、[]、call/apply/bind、new 等任何方式显式关联对象。
-
foo()→ 默认绑定(最典型) -
obj.method()→ 隐式绑定,不是默认绑定 -
const fn = obj.method; fn();→ 表面像方法,实际是独立调用,触发默认绑定 -
setTimeout(obj.method, 100)或button.addEventListener('click', obj.handleClick)→ 回调被剥离上下文,也属于默认绑定
查执行环境:是否启用严格模式
严格模式直接改变默认绑定的行为,必须明确检查代码中是否存在 'use strict' 声明(可作用于全局或函数级)。
- 非严格模式下:
this指向全局对象(浏览器是window,Node.js 是globalThis) - 严格模式下:
this为undefined,访问this.xxx会直接报错,比如TypeError: Cannot read property 'a' of undefined - 箭头函数不参与默认绑定——它根本没有自己的
this,始终沿用外层词法作用域的值,不受严格模式影响
辨特殊上下文:全局、自执行、定时器、事件监听器
这些看似不同的场景,只要函数是独立调用,就统一按默认绑定处理:
- 全局作用域中直接写的
this(如脚本顶层)→ 指向window(非严格)或undefined(严格) - IIFE(立即执行函数):
(function(){ console.log(this); })();→ 默认绑定,结果同上 -
setTimeout(foo, 100)中的foo→ 被引擎以普通方式调用,触发默认绑定 - 事件回调:
btn.onclick = foo;,点击时执行的foo()→ 同样是独立调用,走默认绑定(注意:这和btn.onclick = function(){ console.log(this); }不同,后者this指向btn,属于隐式绑定)
验实际值:用简单语句快速验证
遇到不确定的情况,加一行诊断代码即可确认:
-
console.log(this === window);—— 浏览器中返回true表示非严格默认绑定 -
console.log(this);—— 直接打印,看是window、undefined还是其他对象 -
console.log(this?.constructor?.name);—— 安全检查构造器名,避免undefined报错

















