Подтвердить что ты не робот

JavaScript: получить значение аргумента и имя пропущенной переменной

То, что я хочу сделать, это получить ИМЯ переменной, передаваемой в функцию, и ЗНАЧЕНИЕ этой переменной, и ей нужно передать только одну переменную в функцию. Так:

var x = "anything";

function showName() {

}

showName(x);

или же

showName("x");

Который вернется: "х = что-нибудь".

Прямо сейчас я должен указать переменную дважды:

showName("x", x);

Чтобы получить имя и значение переменной, которую я передаю.

Обратите внимание, что меня интересует не имя аргумента в прототипе showName, а имя переменной в вызывающей функции. Кроме того, передаваемая переменная может быть локальной, поэтому я не могу использовать объект окна, чтобы найти переменную.

4b9b3361

Ответ 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()