如何在JavaScript函数中获取作为参数传入的原始变量名?
好问题!很遗憾的是,在标准JavaScript中,没有可靠的原生方法能直接获取作为函数参数传入的变量的原始名称。
为什么你的测试代码拿不到原始变量名?
当你调用foo(someVariable)时,JavaScript只会把someVariable的值(这里是数组的引用)传递给函数的variable参数——变量名本身并没有被传递到函数内部。你在函数里用varToString({ variable })拿到的"variable",只是函数内部的参数名,和外部的someVariable没有任何关联。
之前你在外部能用varToString({ someVar })拿到变量名,是因为ES6的对象字面量简写语法:{ someVar }等价于{ someVar: someVar },这个对象的键名是你写代码时就固定的字符串"someVar",并不是从变量值里提取出来的。
可行的替代方案
如果确实需要在函数里获取变量名,有两种相对靠谱的方式:
1. 主动传递包含变量名和值的对象
这是最可靠的方案,调用时用对象包裹变量,利用对象字面量简写把变量名转成键名:
function foo(varObj) { // 获取对象的唯一键名(也就是原始变量名) const originalVarName = Object.keys(varObj)[0]; // 获取对应的值 const value = varObj[originalVarName]; console.log(`原始变量名:${originalVarName}`); console.log(`变量值:`, value); } const someVariable = ['string', 'another string']; // 调用时用对象包裹变量 foo({ someVariable });
输出结果:
原始变量名:someVariable 变量值: ["string", "another string"]
2. 调试场景下利用调用栈(不推荐生产环境)
如果只是临时调试,可以通过Error.stack解析调用栈来尝试提取变量名,但这个方法非常脆弱:
- 不同浏览器/Node.js环境的调用栈格式不一致
- 代码压缩后变量名会被混淆(比如变成
a、b) - 无法处理复杂的调用场景(比如表达式作为参数传入)
示例代码:
function foo(variable) { try { throw new Error(); } catch (e) { // 提取调用栈的第三行(不同环境可能需要调整索引) const callLine = e.stack.split('\n')[2]; // 匹配函数调用时的参数部分 const match = callLine.match(/foo\(([^)]+)\)/); if (match) { console.log('推测的原始变量名:', match[1]); } } } const someVariable = ['string', 'another string']; foo(someVariable);
在Chrome浏览器里可能输出推测的原始变量名: someVariable,但其他环境可能无法正常工作,所以只能用于临时调试,绝对不能用于生产代码。
总结
JavaScript的参数传递机制本身不会保留变量的原始名称,所以正式业务场景下,最稳妥的方式是主动传递变量名(比如用对象包裹)。依赖调用栈的黑科技只能作为调试辅助,不具备通用性和可靠性。
内容的提问来源于stack exchange,提问作者Sara Ree

