JavaScript:获取传递变量的参数值和名称

IT技术 javascript arguments
2021-02-01 15:05:39

我想要做的就是传递给函数的变量的名称该变量的值,并且只在一个变量传递给函数。所以:

var x = "anything";

function showName() {

}

showName(x);

或者

showName("x");

这将返回:“x = 任何东西”。

现在,我必须两次指定变量:

showName("x", x);

为了获取我传入的变量的名称和值。

请注意,我对 showName 原型中的参数名称不感兴趣,而是对调用函数中的变量名称感兴趣。此外,传递的变量可能是本地的,因此我无法使用 window 对象来查找变量。

6个回答

简短的回答是你不能。

更长的,邪恶的答案是你可以带着一些真正的肮脏。它仅在从另一个函数调用时才有效。

有两个有趣的属性可以帮助您

arguments.callee 调用者

让 fn 做这样的事情:

(function(){
  var showMe = function(s){
    alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] + 
    ' = '+ s)
  }
  x = 1
  showMe(x)
})()

arguments.callee.caller.toString().match(..)[1] 的作用是查找在调用它的函数中调用的 showMe 并打印它及其值。

但这仍然非常有限,因为它只会触发 showMe(x) 的第一次调用。因此,如果有两次调用它,它将不起作用。

但是,玩这些神秘的东西很有趣。

这将当Firefox和Safari错误callernull
2021-03-29 15:05:39
@Jhawins 真的。如果您可以以某种方式获得对源字符串的引用,那么可能有一种解决方法。
2021-03-30 15:05:39
+1,恶心又迷人。
2021-03-31 15:05:39
自 ECMAScript (ES5) 起已弃用 :(
2021-04-11 15:05:39

策略一:

如果您可以在函数调用期间控制数据结构,那么您可以传递一个字典,该字典将名称编码为键,与其值配对,注意隐形花括号:

var foo = "bar";
yourfunction({foo});

它传递了一个如下所示的 javascript 字典:

{foo : "bar"}

yourfunction(被执行时,解包名称和值thustly:

yourfunction = function(dict) { 
    var name = Object.keys(dict)[0];
    var value = dict[name];
    console.log(name);        //prints foo
    console.log(value);       //prints bar
}

策略二:

如果您可以在全局范围内维护一个随时可用的名称-值对列表,那么反射和内省始终可用于 set 和 get,例如:

var my_global_stack = [];

yourfunction = function() { 

    //Chomp the stack
    var dict = my_global_stack.pop();

    //The name is the key at index 0
    var name = Object.keys(dict)[0];

    //Fetch the value by keyname:
    var value = dict[name];

    console.log(name);       //prints foo
    console.log(value);      //prints bar
}


foo = "bar";
my_global_stack.push({foo});
yourfunction();

策略三:

如果用户敌对输入不是问题,您可以使用eval(给定变量名重新发现值,例如:

yourfunction = function(somevariable) { 
    console.log(somevariable);          //prints foo
    console.log(eval(somevariable));    //prints bar
}

foo = "bar";
yourfunction("foo");

人们eval(在这里是邪恶的,因为如果敌对用户能够foo在任何时候覆盖内存中的值,那么他们就可以进行操作系统命令注入并运行他们想要的任何命令。
http://cwe.mitre.org/top25/#Guidance

不需要你自己的全局变量,也不需要 eval,看看我的回答。
2021-04-05 15:05:39
var x = "anything";

function showName(s) {
    alert(s + " = " + eval(s));
}

showName("x");

不推荐,但它就在那里。

x=1呢?节目名称(x) ?
2021-03-18 15:05:39
@BaroqueBobcat - 上述功能对我来说很好用。如果您正在寻找边缘情况,则可以轻松修改该函数以根据类型或值以不同方式对数据进行字符串化。例如,空数组和空字符串都显示为空。您可能希望以不同的方式处理此问题,或添加有关键入的最佳猜测的附加信息。该示例的重点不是防弹,而是演示一个函数可以从一个标量参数获取参数名称和值。
2021-04-04 15:05:39

您可以创建一个哈希并将其传入:

var x = {a: 1,b:2}
function showVars(y) {
    for (var z in y) { alert(z + " is " + y[z]); }
}
showVars(x);

这不一定显示变量的名称,但它确实允许键值对,这可能更符合您的需要。

这永远不会打印 x = {a: 1,b:2},所以它不是 OP“需要”的
2021-03-15 15:05:39

这是我用来调试的。没有全局变量,没有 eval,没有 arguments.callee 或 arguments.caller:

var Helpers = (function () {
    // ECMAScript 5 strict mode
    'use strict';

    var Module = {};

    Module.debug = function () {
        var i;

        for (i = 0; i < arguments.length; i++) {
            console.log(arguments[i] + ':', this[arguments[i]]);
        }
    };

    Module.SomeObject = function SomeObject() {
        this.someMember = 1;
        this.anotherMember = 'Whatever';

        Module.debug.call(this, 'someMember', 'anotherMember');

        var privateMember = {
            name: 'Rip Steakface',
            battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!'
        };

        Module.debug.call(privateMember, 'name', 'battleCry');
    };

    return Module;
}());

对于那些想知道为什么要这样做的人来说,这只是一种有效地记录多个变量及其名称的方法。

如果您希望能够记录嵌套成员,如Module.debug.call(obj, 'hair.fluffiness'),您可以像这样修改函数:

Module.debug = function () {
    var i, j, props, tmp;

    for (i = 0; i < arguments.length; i++) {
        tmp = this;
        props = arguments[i].split('.');

        for (j = 0; j < props.length; j++) {
            tmp = tmp[props[j]];
        }

        console.log(arguments[i] + ':', tmp);
    }
};

不幸的是,我找不到任何方法来有效地记录不是对象成员的多个私有变量,例如 var roll = 3, value = 4; Module.debug.call(???);