JavaScript反射:获取变量的名称?

iyr7buue  于 2023-01-07  发布在  Java
关注(0)|答案(5)|浏览(335)

我有几个变量被赋给同一个函数。属性'name'是"",因为这个函数是匿名的;
也没有涉及函数调用,因此没有被调用方。
在JS中有没有一种方法可以通过自实现的反射算法来获取变量的名称?

    • 例如**
var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;
    • 背景**:

为了节省空间,数千个变量名被分配给同一个"静态"函数,作为一个惰性加载的stumps,在第一次调用时,这些stumps被解析为单个函数。(变量名还包含一个命名空间)。

    • 备选方案**:

我的替代方法是使用{_name: myUnknownNamedVar1 , _fn: x}之类的对象
这个问题的解决方案会很有趣。一个特殊的问题是辨别脚本中指向同一对象的不同名称的变量。

cclgggtu

cclgggtu1#

可以使用对象反射,如下所示:

const getVarName = obj => Object.keys(obj)[0];
const varToGetTheNameOf = "Value!";
getVarName({ varToGetTheNameOf }) // => "varToGetTheNameOf"
new9mtju

new9mtju2#

不,没有。
一个简单的解释(强调了帖子中的观点)很简单:一个变量(或属性)不是一个值/对象。2相反,它是一个值/对象的"名字"。3同一个对象可以被多次命名。
想象一下这个例子,并考虑它如何Map到给人的"名字":-)

var fred = function Fred () {}
fred.name // "Fred"

// An unknown number of nicknames can exist...
var francisco = fred
var frankyTheFiveFingers = fred
someOtherRegion.theGoodPerson = fred

// But sometimes nicknames are known; note that this is
// a locatable (e.g. "known") iterable set.
// (While properties can be iterated, variables cannot.
//  However, iterating *every* object is not feasible, hence
//  it must be a locatable set.)
fred.nicknames = ["Freddy", "FD"]

mary.nicknamesFor(fred) // who knows :-)

编程愉快。

a6b3iqyw

a6b3iqyw3#

1.您可以尝试解析脚本文本。

JSFiddle Example

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

var txt  = (document.currentScript && document.currentScript.textContent) ||
           (document.scripts       && document.scripts[1]
                                   && document.scripts[1].textContent);
var arr  = txt.match(/var\s*(.*)\s*=\s*x\b/);
arr[1]   = arr[1].replace(/\s+$/,"");
var vars = arr[1].split(/\s*=\s*/);

// vars: ["myUnknownNamedVar1", "myUnknownNamedVar2"]

2.您可以尝试比较值

JSFiddle Example

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

var vars = [];
for (var prop in window){
    if (window[prop] == x)
      vars.push(prop);
}

// vars: ["x", "myUnknownNamedVar1", "myUnknownNamedVar2"]

***注意:*这两个方法都需要改进(例如递归,更好/更多的匹配模式)。第二个方法只查看全局变量,而闭包中的一些变量可能不会暴露给全局名称空间。还有对象的对象。

cfh9epnr

cfh9epnr4#

您可以使用装饰器来检测变量的名称,该变量必须是:
(a)-类别
(b)-类或示例的属性
(c)-类或示例的方法
装饰者提供关于装饰的3个信息:
1.靶
1.钥匙
1.描述符
因此:

  • (a)的名称是target.name
  • (B)或(c)的名称直接为key
function logName(target, key) {
   console.log(!key ? target.name : key);
 }

示例(Try Fiddle

@logName
  class Person {

     @logName
     firstname="Someone";

     @logName
     fullName() {
       return this.firstname+' '+this.lastname;
     }

  }

Try Fiddle

ddhy6vgd

ddhy6vgd5#

您可以使用的一个技巧如下所示:

let myVariable = 1;
console.log((()=>myVariable).toString().replace('()=>', ''))

相关问题