JavaScript中如何判断两个函数是否指向同一引用?
嘿,针对你遇到的这个问题,先给你一个最直接的结论:JavaScript里的===运算符,本身就是判断两个函数是否指向同一内存引用的最靠谱方式——这正是它的核心用途之一。你提到的this.fn1 === this.json1.fn1返回true/false的场景,其实已经在做最准确的引用判断了。
你说用function.toString()没效果?太正常了,匿名函数(尤其是经过JS引擎优化后的)的toString输出通常会被统一处理,比如很多环境里都会返回function() { [native code] }或者简化的函数体,根本没法区分不同的匿名函数实例,所以这个方法确实行不通。
下面给你拆解几个关键点和补充方案:
先搞懂引用相等的本质
只有当两个函数变量指向内存里同一个函数对象的时候,===才会返回true。如果this.fn1和this.json1.fn1是两个不同的匿名函数实例(哪怕代码写得完全一样),===返回false是完全正确的——因为它们本来就是两个独立的引用,不是同一个东西。如果你的需求是判断函数逻辑是否相同(而非是否同一引用)
要是你实际想确认的是两个函数的功能、代码逻辑是否一致(而不是是否指向同一个内存地址),可以试试这个优化思路:- 先用
===快速判断引用相等的情况(这一步能省很多事); - 对于不同引用的函数,对
toString()的结果做标准化处理后再比较,比如去掉空格、换行、注释,统一格式:
function areFunctionsLogicEqual(fnA, fnB) { if (fnA === fnB) return true; // 标准化函数体:清除无关格式和注释 const normalize = fn => fn.toString() .replace(/\s+/g, '') .replace(/\/\/.*$/gm, '') .replace(/\/\*[\s\S]*?\*\//g, ''); return normalize(fnA) === normalize(fnB); }不过要提醒你:这种方法有局限性,如果函数内部依赖了闭包变量,哪怕代码文本完全一样,实际执行逻辑可能天差地别,这时候文本比较就失效了。
- 先用
调试时的小技巧
如果你在调试过程中想快速区分不同的函数引用,可以给每个函数实例加一个唯一标识属性,比如:// 创建带唯一ID的匿名函数 const createUniqueFn = (fn) => { fn.__uniqueFnId = Symbol('unique-function-id'); return fn; }; // 判断时结合引用和自定义ID function areSameFunctionReference(fnA, fnB) { if (fnA === fnB) return true; // 兜底判断自定义ID return !!fnA.__uniqueFnId && !!fnB.__uniqueFnId && fnA.__uniqueFnId === fnB.__uniqueFnId; }当然,这个方法需要你能控制函数的创建过程,如果是第三方库生成的函数,可能没法加这个属性。
最后再总结下:
- 优先用
===判断引用是否相同,这是原生方法里最可靠的; - 如果要判断逻辑相同,用标准化后的
toString()比较,但要注意闭包等边界情况; - 自定义唯一标识适合你能控制函数创建的场景。
内容的提问来源于stack exchange,提问作者Pratik

