JavaScript Reflection:获取变量的名称?

发布于 2024-12-11 03:55:56 字数 530 浏览 0 评论 0原文

我有几个变量被分配给同一个函数。属性“name”是“”,因为该函数是匿名的;

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

JS中有没有办法通过自己实现的反射算法来获取变量的名称?

例如

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

背景

为了空间效率,数千个变量名称被分配给与延迟加载树桩相同的“静态”函数,这些变量名称在第一个时被解析为单独的函数调用调用。 (变量名还包含命名空间)。

替代方案

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

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

I have a several variables which are assigned to the same function. The property 'name' is "" as this function is anonymous;

There also isn't a function call involved, and as such no callee.

Is there a way in JS to obtain the variable's name, through a self-implemented reflection algorithm?

e.g.

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

Background:

for space efficiency, thousands of variable names are assigned to the same 'static' function as a lazy-loaded stumps, which get resolved to individual functions upon the first call invocation. (The variable name also contains a namespace).

Alternatives:

My alternative would be the use of objects such as {_name: myUnknownNamedVar1 , _fn: x}

Solutions to this issue would be interesting. A particular issue is discerning variables with different names ,in the script, which point to the same object.

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

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

发布评论

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

评论(5

悲歌长辞 2024-12-18 03:55:56

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

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

It is possible to use object reflection, as such:

const getVarName = obj => Object.keys(obj)[0];
const varToGetTheNameOf = "Value!";
getVarName({ varToGetTheNameOf }) // => "varToGetTheNameOf"
莳間冲淡了誓言ζ 2024-12-18 03:55:56

不,没有。

对此的一个简单解释(强化了帖子中的观点)很简单:变量(或属性)不是值/对象。相反,它是值/对象的“名称”。同一个对象可以被命名多次。

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

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

快乐编码。

No. There is not.

A simple explanation (that reinforces the point in the post) for this is simply: a variable (or property) is not a value/object. Rather, it is a "name" for a value/object. The same object can be named multiple times.

Imagine this example, and consider how it maps to "names" given to people :-)

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

Happy coding.

喵星人汪星人 2024-12-18 03:55:56

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

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

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

1. You could try parsing the script's text.

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. You can try comparing values

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

Note: Both methods will need refining (eg recursion, better/more match patterns). The second one only looks at global variables, whereas some variables in closures may not be exposed to the global namespace. Also, there are objects of objects.

初吻给了烟 2024-12-18 03:55:56

您可以使用装饰器来检测变量的名称,该变量必须是:

(a)- 类

(b)- 类或实例的属性

(c)- 类或实例的方法


装饰器提供有关装饰的 3 个信息:

  1. 目标
  2. 描述符

因此:

  • (a)的名称是target.name
  • (b)或(c)的名称直接是key

     function logName(目标, key) {
       console.log(!key ? target.name : key);
     }
    

示例(尝试小提琴) :

  @logName
  class Person {

     @logName
     firstname="Someone";

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

  }

尝试 Fiddle

You can use decorators to detect the name of variable that must be :

(a)- Class

(b)- Attribute of class or of instance

(c)- Method of class or of instance


The decorator provides 3 informations about the decorated :

  1. target
  2. key
  3. Descriptor

Thus:

  • the name of (a) is target.name
  • the name of (b) or (c) is key directly

     function logName(target, key) {
       console.log(!key ? target.name : key);
     }
    

example (Try Fiddle) :

  @logName
  class Person {

     @logName
     firstname="Someone";

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

  }

Try Fiddle

舂唻埖巳落 2024-12-18 03:55:56

你可以做的一个技巧是这样的:

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

One trick you can do is something like this:

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

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