Strict Mode下如何提取传入函数引用的内部定义变量?
JavaScript严格模式下提取闭包内部变量的可行方案
JavaScript 标准没有提供直接访问闭包内部变量的官方反射API,严格模式下禁用了arguments.caller等可间接获取调用上下文的属性,你预期的直接读取函数内部Scopes闭包属性的方式无法在标准兼容运行时中实现,这是JS作用域安全的设计限制。
结合你可完全控制targetObj的前提,有两个可落地的实现方案:
方案1:静态分析函数源码
通过functionRef.toString()可以拿到传入函数的源代码,再通过正则匹配提取比较逻辑对应的变量值,严格模式下可正常使用:
const tryReadInternalVarValue = function(functionRef) { const targetObj = { title: "World" }; const isMatch = functionRef(targetObj); if (!isMatch) { throw Error(``); } // 提取内部变量值逻辑 const funcSource = functionRef.toString(); // 匹配和title做比较的变量名 const compareVarName = funcSource.match(/passingThisObject\.title\s*===\s*(\w+)/)?.[1]; if (compareVarName) { // 匹配该变量的赋值语句提取值 const valueMatch = funcSource.match(new RegExp(`const\\s+${compareVarName}\\s*=\\s*["']([^"']+)["']`)); if (valueMatch) { console.log('提取到的internalVariable值:', valueMatch[1]); // 输出Hello } } return isMatch; }
局限:仅适用于结构固定、无动态生成逻辑的函数,若传入函数经过压缩或赋值逻辑复杂,需要调整正则匹配规则。
方案2:多轮调用反推内部变量值
如果内部变量的可选范围有限,可以通过传入不同title值的测试对象调用传入函数,根据返回的匹配结果反推内部变量值,完全不依赖函数源码结构:
const tryReadInternalVarValue = function(functionRef) { // 反推内部变量值 const testTitles = ["Hello", "World", "Test1", "Test2"]; let internalVariable = null; for (const title of testTitles) { if (functionRef({ title })) { internalVariable = title; break; } } console.log('反推得到的内部变量值:', internalVariable); // 输出Hello const targetObj = { title: "World" }; return functionRef(targetObj); }
已尝试方案的问题说明
arguments.caller属于非标准遗留属性,ES5严格模式明确禁用,无标准兼容替代方案。- 之前的Proxy方案没有生效,是因为你代理的是函数的
this指向,而你调用functionRef时是直接把targetObj作为参数传入,没有用到this,所以Proxy陷阱不会触发。如果要代理参数,需要把Proxy实例作为参数传给functionRef。
内容的提问来源于stack exchange,提问作者MMS
相关产品推荐
相关产品推荐

