JavaScript: получить значение аргумента и имя пропущенной переменной
То, что я хочу сделать, это получить ИМЯ переменной, передаваемой в функцию, и ЗНАЧЕНИЕ этой переменной, и ей нужно передать только одну переменную в функцию. Так:
var x = "anything";
function showName() {
}
showName(x);
или же
showName("x");
Который вернется: "х = что-нибудь".
Прямо сейчас я должен указать переменную дважды:
showName("x", x);
Чтобы получить имя и значение переменной, которую я передаю.
Обратите внимание, что меня интересует не имя аргумента в прототипе showName, а имя переменной в вызывающей функции. Кроме того, передаваемая переменная может быть локальной, поэтому я не могу использовать объект окна, чтобы найти переменную.
Ответы
Ответ 1
Короткий ответ заключается в том, что вы не можете.
Более длинный, злой ответ - это то, что вы можете с некоторой реальной гадостью. И он работает только при вызове из другой функции.
доступно два интересных атрибута, которые могли бы помочь
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). Поэтому, если есть два вызова, это не сработает.
Но было весело играть с этими загадочными вещами.
Ответ 2
var x = "anything";
function showName(s) {
alert(s + " = " + eval(s));
}
showName("x");
Не рекомендуется, но есть.
Ответ 3
Стратегия 1:
Если вы можете управлять структурой данных во время вызова функции, тогда вы можете передать словарь, который закодирует имя как ключ, в сочетании с его значением, обратите внимание на скрытые фигурные скобки:
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:
Если вы можете поддерживать список пар "имя-значение" по мере необходимости в глобальной области видимости, тогда рефлексия и самоанализ всегда доступны для установки и получения, например:
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(
для повторного обнаружения значения с помощью имени переменной, например:
yourfunction = function(somevariable) {
console.log(somevariable); //prints foo
console.log(eval(somevariable)); //prints bar
}
foo = "bar";
yourfunction("foo");
Люди говорят, что eval(
здесь зло), потому что если враждебный пользователь может в любой момент перезаписать значение foo
в памяти, он может сделать OS Command Injection и выполнить любую команду, какую захочет.
http://cwe.mitre.org/top25/#Guidance
Ответ 4
Вы можете создать хэш и передать это в:
var x = {a: 1,b:2}
function showVars(y) {
for (var z in y) { alert(z + " is " + y[z]); }
}
showVars(x);
Это не обязательно показывает имя переменной, но она позволяет пары ключ-значение, которые могут быть более точными, что вам нужно.
Ответ 5
Это то, что я использую для отладки. Нет глобальных переменных, нет eval, no 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(???);
Ответ 6
Не уверен, что вы можете напрямую получить то, что хотите от 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" } )
Ответ 7
Ниже приведено описание того, что вы можете сделать. К сожалению, локальные переменные в функции являются свойствами скрытого объекта вызова, поэтому они не могут быть доступны из Javascript, например window [a], где a является свойством объекта window.
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()