JS怎么获取变量名称(反射)

发布于 2022-09-12 02:10:37 字数 633 浏览 25 评论 0

JS中怎么在程序执行的时候,获取变量名称。

比如通过一个函数返回指定参数的参数名。

jsvar paramName = 'asdf' // 不管等于什么。
var paramName2 = new Object(); // 不管等于什么。

function getParamName(p) {
    // ...实现过程
    var result = ...; // 这里只是模拟
    return result;
}

getParamName(paramName);
getParamName(paramName2);

最终参数的返回结果应该为:

output  Output:
  paramName
  paramName2

请问,类似的需求怎么实现,有没有变通的方法?

看了一下,感觉 http://segmentfault.com/q/1010000002761696#a-1020000002765874 说的比较合理。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

强者自强 2022-09-19 02:10:37

2017.1.5 答案已重写

每一个上下文都有一个与之对应的变量对象,任何声明的变量都是这个变量对象的属性。全局上下文的变量对象是全局对象,因而在全局声明的变量就变成了全局对象的属性。相应地,函数上下文的变量对象是活化对象,在函数上下文声明的变量是活化对象的属性。然而,活化对象是引擎内部的一个对象,不可被外部访问,因而不可在 JS 中获取函数上下文变量的名称。

此外基本类型的函数实参是以传值的方式传入函数的,对象类型的实参是以引用的方式传入函数的,无论哪种方式,函数都只能得到传入的值或者引用,而无法访问调用函数的上下文的变量对象,因而不能在函数内部获得传入函数的变量的名称。

既然没有函数能够返回调用这个函数的上下文中变量的名称,JS 也没有提供能做到这件事的操作符,那么在执行上下文内部获取该执行上下文内部变量的名称也就是不可能的。

当然啦,对于函数代码的执行上下文,如果我们能获得这个函数的代码,就可以解析这段代码得到这段代码当中变量的名称。

示例代码:

function getParamName() {}

function fn() {
  var param1 = 0
  var a = 2

  console.log(getParamName(param1))
  console.log(getParamName(a))
}

function callWithVariableName(fn) {
  eval('(' + fn.toString().replace(/\bgetParamName\s*\(([a-zA-Z_$][\w_$]*)\)/g, function(u, v) {
    return "'" + v + "'"
  }) + '())')
}

callWithVariableName(fn)

控制台输出:

param1
a
酒儿 2022-09-19 02:10:37

no way,不止JS,Java和C#的反射也搞不出来吧

梦毁影碎の 2022-09-19 02:10:37

这个在js中是不成立的, 变量名这个东西只是为了方便对象参数的传递才出来的,修改成任意其他名字,解析器解析结果都没有影响,从代码混淆工具可以随意修改这些名称就可以看出。 如果你硬要做这种规则,那自己就得额外给出一些规则,而这些规则是处于javascript解析器之外的, 变味儿了。

浮华 2022-09-19 02:10:37

可以将变量写入一个json,形如:
var json={paramname:value}
然后
for(var key in json)
通过json[key]获取value比较传入值,符合就返回key。

不知能否满足你的需求

冰葑 2022-09-19 02:10:37

难度有点高,这应该有关于 JS 的反射技术,类似于 Java 的反射。

sf.gg历史提问中有两份资料:
《JavaScript反射机制到底是什么?》:http://segmentfault.com/q/1010000002761696
《JavaScript反射机制与继承:概念》:http://segmentfault.com/a/1190000000593171

请求大家帮帮忙!

白色秋天 2022-09-19 02:10:37

题主跟我想法一样啊!不过应该是不能实现的。
我当时问的是C#的:
http://segmentfault.com/q/1010000002592470
http://segmentfault.com/q/1010000002588785

百善笑为先 2022-09-19 02:10:37

一楼的回答已经很完善了,给出了一种静态修改函数代码实现在函数内部获得变量名的方法,那我就把这件事更进一步,省去在函数外部修改函数代码的麻烦

function enableGetVariableName(fn) {
  return eval('(' + fn.toString().replace(/return enableGetVariableName\([^\)]+\)\.apply\(this, arguments\)/g, '').replace(/\b(?:getParamName)\s*\(([a-zA-Z_$][\w_$]*)\)/g, function(u, v) {
    return "'" + v + "'"
  }) + ')')
}

function fn() {
  return enableGetVariableName(fn).apply(this, arguments)

  var param1 = 0
  var a = 2

  console.log(getParamName(param1))
  console.log(getParamName(a))
}

fn()

唯一要做的只是在函数开头加一句,

return enableGetVariableName(fn).apply(this, arguments) // fn 是函数的名字

控制台输出:

param1
a
枯叶蝶 2022-09-19 02:10:37

取个临时变量就好了,不取全局对象

function getKeyName(kv) {
  for (let i in kv) {
    return i;
  }
  return false;
}

let a = "123";
let b = { a };
console.log(getKeyName(b));
濫情▎り 2022-09-19 02:10:37

我现在也遇到这个问题了,js获得函数的函数名称
function a(){}
alert(a.name)//a
var b=function(){}
获得不了b的名称!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文