嵌套普通函数会丢失this,因其this动态绑定且取决于调用方式;直接调用触发默认绑定(非严格模式指向window,严格模式为undefined);可用that/self缓存、箭头函数继承外层this或bind显式绑定解决。

对象方法里写嵌套的普通函数,this 会丢,是因为普通函数的 this 是动态绑定的——它只看“谁调用它”,不看“它写在哪”。一旦嵌套函数脱离了对象方法的调用形式(比如传给 setTimeout、addEventListener 或直接调用),就变成独立函数调用,触发默认绑定:非严格模式下指向 window,严格模式下是 undefined。
为什么嵌套普通函数会丢失 this
关键不是“嵌套”本身,而是调用方式变了。例如:
const obj = {
name: 'Tom',
say() {
function inner() { console.log(this.name); }
inner(); // ❌ this 指向 window 或 undefined,不是 obj
}
};
这里 inner() 是直接调用,没有通过 obj.say().inner() 这种方式,所以它和 obj 完全无关。
用 that / self 缓存外层 this
在嵌套前把当前 this 存下来,嵌套函数里用变量访问,兼容性最好,逻辑最直白:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 在方法开头声明
const that = this;或const self = this; - 嵌套函数里统一用
that.xxx或self.xxx访问属性或方法 - 适合老项目、需要支持 IE 或复杂生命周期场景
obj.say = function() {
const that = this;
setTimeout(function() {
console.log(that.name); // ✅ 正确输出 'Tom'
}, 100);
};
用箭头函数替代嵌套普通函数
箭头函数没有自己的 this,自动继承外层函数作用域的 this,写起来简洁,语义清晰:
- 只要外层是对象方法(且 this 指向正确),箭头函数就能“跟着走”
- 不能用于构造函数或需要动态 this 的场景
- 注意:对象字面量中直接写
fn: () => {...}不行——此时外层没有 this 绑定,会继承全局上下文
obj.say = function() {
setTimeout(() => {
console.log(this.name); // ✅ this 仍是 obj
}, 100);
};
用 bind 显式绑定 this
对已存在的普通函数,用 .bind(this) 创建一个新函数,确保执行时 this 固定:
- 适合复用已有函数,或需提前配置好上下文
- 每次 bind 都返回新函数,避免在 render 或循环里反复调用
- 常见于事件监听、定时器、数组方法回调等场景
obj.say = function() {
function inner() { console.log(this.name); }
setTimeout(inner.bind(this), 100); // ✅ this 绑定到 obj
};
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










