
Map 存储函数时不会自动绑定 this,所以“键名”本身不引发丢失,真正风险在于——从 Map 中取出函数并直接调用。此时函数脱离原始对象调用链,this 指向就断了。
为什么 Map.get() 取出的函数会丢 this
Map 本质是键值容器,它不干预函数的绑定逻辑。当你把一个对象方法存进 Map:
- const obj = { name: 'Alice', greet() { return `Hello, ${this.name}`; } };
- const fnMap = new Map(); fnMap.set('greet', obj.greet);
- const fn = fnMap.get('greet'); fn(); // ❌ this 是 undefined(严格模式)
这里 obj.greet 被取出来赋值给变量 fn,和 const fn = obj.greet 完全等价——函数已脱离 obj,调用时自然失去上下文。
哪些操作容易误触 this 丢失
- 用
Map.get(key)()直接执行:没经过对象点调用,this 断开 - 把 Map 中的函数传给
setTimeout、addEventListener或Promise.then - 在数组方法中使用:
list.map(Map.get('process'))—— 同样是裸函数调用 - 解构 Map 值:
const { process } = Object.fromEntries(map); process()(虽非原生 Map 操作,但常见于转换后误用)
如何安全地从 Map 调用函数并保留 this
- 调用时显式绑定:
fnMap.get('greet').call(obj)或.apply(obj) - 存入时就绑定:
fnMap.set('greet', obj.greet.bind(obj))(适合固定目标对象) - 用箭头函数包装存储:
fnMap.set('greet', () => obj.greet())(适合简单封装) - 类中推荐类字段语法:
handler = () => this.doSomething(),再存入 Map,调用即安全
快速识别风险代码的信号
- 看到
map.get(...)(...)连写,且前面没做 bind/call/箭头包装 - Map 值来自
obj.method形式提取,而非() => obj.method()或obj.method.bind(obj) - 控制台报错类似
Cannot read property 'xxx' of undefined,且出错位置在 Map 取出的函数内部










