JavaScript反射:获取变量的名称

JavaScript Reflection: obtaining a variable's name?

本文关键字:变量 获取 反射 JavaScript      更新时间:2023-09-26

我有几个变量被分配给相同的函数。属性'name'是",因为这个函数是匿名的;

也不涉及函数调用,因此没有被调用方。

是否有一种方法在JS中获得变量的名称,通过一个自我实现的反射算法?

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

:

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

替代

:

我的替代方案是使用诸如{_name: myUnknownNamedVar1 , _fn: x}

这样的对象

这个问题的解决方案会很有趣。一个特殊的问题是在脚本中识别具有不同名称的变量,这些变量指向同一个对象。

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

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

No。There is not.

一个简单的解释是:变量(或属性)是而不是值/对象。相反,它是值/对象的"名称"。同一个对象可以多次命名。

想象一下这个例子,并考虑它如何映射到给人们的"名字":-)

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 :-)     

快乐编码。

您可以尝试解析脚本的文本。

JSFiddle例子

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例子

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"]

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

您可以使用修饰符来检测必须是:

(一)——类

(b)-类或实例的属性

(c)-类或实例的方法


装饰器提供了关于被装饰者的3个信息:

  1. <
  2. 键/gh>
  3. 描述符

:

  • (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;
     }
  }

尝试小提琴

你可以这样做:

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