我想要做的是将变量的NAME传递给函数和该变量的VALUE,并且只需要将一个变量传递给函数。所以:
var x = "anything";
function showName() {
}
showName(x);
或
showName("x");
将返回:“x =任何东西”。
现在,我必须指定两次变量:
showName("x", x);
为了获取我传入的变量的名称和值。
请注意,我对showName原型中的参数名称不感兴趣,但是对调用函数中的变量名称不感兴趣。此外,传递的变量可能是本地的,因此我无法使用window对象来查找变量。
答案 0 :(得分:58)
简短的回答是,你不能。
更长,更邪恶的答案是你可以带着一些真正的肮脏。它只能在从另一个函数调用时才有效。
有两个有用的属性可以提供帮助
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)的第一个调用。因此,如果有两个调用它,它将无法正常工作。
但是,玩这些神秘的东西很有趣。
答案 1 :(得分:8)
var x = "anything";
function showName(s) {
alert(s + " = " + eval(s));
}
showName("x");
不推荐,但确实存在。
答案 2 :(得分:5)
策略1:
如果你可以在函数调用期间控制数据结构,那么你可以传递一个字典,它将name作为一个键,与它的值配对,注意隐形花括号:
var foo = "bar";
yourfunction({foo});
它传递了一个如下所示的javascript字典:
{foo : "bar"}
执行yourfunction(
时,请彻底解压名称和值:
yourfunction = function(dict) {
var name = Object.keys(dict)[0];
var value = dict[name];
console.log(name); //prints foo
console.log(value); //prints bar
}
策略2:
如果您可以在全局范围内维护名称 - 值对的即用列表,那么反射和内省始终可用于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();
策略3:
如果用户恶意输入不是问题,您可以使用eval(
重新发现给定variablename的值,例如:
yourfunction = function(somevariable) {
console.log(somevariable); //prints foo
console.log(eval(somevariable)); //prints bar
}
foo = "bar";
yourfunction("foo");
人们说eval(
在这里是邪恶的,因为如果恶意用户能够在任何时候在内存中覆盖foo
的值,那么他们可以执行OS命令注入并运行他们想要的任何命令。
http://cwe.mitre.org/top25/#Guidance
答案 3 :(得分:2)
您可以创建一个哈希并将其传递给:
var x = {a: 1,b:2}
function showVars(y) {
for (var z in y) { alert(z + " is " + y[z]); }
}
showVars(x);
这不一定显示变量的名称,但它确实允许键值对,这可能更符合您的需要。
答案 4 :(得分:2)
这是我用于调试的内容。没有全局变量,没有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(???);
答案 5 :(得分:1)
不确定你能直接从JavaScript获得你想要的东西,因为变量名不会带有它引用的值(想象变量名只是编译器知道的标识符;但是在运行时被抛弃。)
你可以,但是,稍微做一些不同的,它允许传递命名参数。创建一个匿名对象并将其传递给您的函数:
function showNames(o)
{
for( var ix in o )
{
alert( ix + ":" + o[ix] );
}
}
var z = { x : "Anything" }
showNames( z );
// or
showNames( { a : "ay", b : "bee", c: "see" } )
对于迭代对象属性,我倾向于选择函数式,如:
Array.iteri = function(o, f)
{
for(var i in o) { f(i, o[i]) }
}
function showNames(o)
{
Array.iteri( o, function(i,v)
{
alert( i + ": " + v )
});
}
showNames( { a : "ay", b : "bee", c: "see" } )
答案 6 :(得分:1)
以下代码是您可以做的最好的代码。不幸的是,函数中的局部变量是隐藏调用对象的属性,因此无法从Javascript中访问它们,如窗口[a],其中a是窗口对象的属性。
x = "this is x";
var say = function(a) {
document.write(a + " = " + window[a]);
}
say("x");
var wrapper = function () {
var x = "this is x";
document.write(x + " = " + eval("x"))
}
wrapper()