多层嵌套函数中 this 的判定关键在于调用方式而非层数:普通函数的 this 由调用者决定,箭头函数无 this 而继承外层首个普通函数的 this;需警惕赋值导致的隐式丢失,建议用箭头函数或 bind 固定 this。

多层嵌套函数里的 this 容易混乱,关键不是“看有多少层”,而是逐层确认每层函数的调用方式,并特别注意箭头函数是否介入。只要抓住“调用点决定 this”这个核心,就能稳住判断逻辑。
先分清函数类型:普通函数 vs 箭头函数
这是理清嵌套中 this 的第一道门槛:
- 普通函数(
function() {}或简写方法meth() {}):有自己的 this,值由它被谁调用决定 - 箭头函数(
() => {}):没有自己的 this,直接继承外层第一个普通函数作用域的 this(即“this 穿透”)
遇到箭头函数,就跳过它,往它的外层找最近的那个普通函数——那个函数的 this 就是它的 this。
看调用链:谁在执行这一层?
不要只看定义位置,要还原运行时的调用路径。例如:
const obj = {
name: 'Alice',
fn1() {
console.log(this.name); // → 'Alice'(obj 调用 fn1)
setTimeout(() => {
console.log(this.name); // → 'Alice'(箭头函数继承 fn1 的 this)
}, 0);
setTimeout(function() {
console.log(this.name); // → undefined(非严格模式下是 window,name 不在其上)
}, 0);
}
};
这里三层调用关系清晰:
-
obj.fn1()→fn1的 this 是obj - 箭头函数 → 没有 this,沿用
fn1的 this,仍是obj - 普通 function 回调 → 独立调用,this 是全局(或
undefined)
警惕“隐式丢失”:赋值后调用就变天
嵌套常发生在回调、定时器、事件绑定中,但真正出问题的往往是函数被提取出来再调用:
-
const handler = obj.fn1; handler();→ 此时handler是独立调用,this 不再是obj -
btn.addEventListener('click', obj.fn1)→ 点击时由btn触发,但fn1是作为回调传入,this 仍丢失(除非用bind或箭头函数包装)
这种场景下,建议统一用箭头函数包裹,或提前 bind(obj),避免嵌套越深越难追溯。
构造函数和 new 场景单独记
如果嵌套出现在构造函数内部(比如类里定义方法再嵌套回调),要记住:
-
new Foo()中,构造函数体内的 this 指向新实例 - 其内部定义的普通函数,若被实例方法调用,this 仍遵循调用者规则
- 但内部箭头函数会自然捕获构造函数的 this(即新实例),适合用来写事件回调











