Javascript: Få Argument Verdi og navn på Bestått Variable

stemmer
42

Hva jeg vil gjøre er å få navnet på en variabel sendes til en funksjon og verdien av denne variabelen, og bare må passere i en variabel til funksjonen. Så:

var x = anything;

function showName() {

}

showName(x);

eller

showName(x);

Som vil returnere: x = noe.

Akkurat nå har jeg å gjøre:

showName(x, x);

for å få navnet og verdien av variabelen jeg passerer i. Legg merke til at jeg ikke er interessert i navnet på argumentet i prototypen av showName, men navnet på variabelen i ringer funksjon. Dessuten kan den variable være lokale, så jeg kan ikke bruke vinduet objektet for å finne variabelen.

Publisert på 17/06/2009 klokken 22:51
kilden bruker
På andre språk...                            


7 svar

stemmer
8
var x = "anything";

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

showName("x");

Ikke anbefalt, men det er det.

Svarte 17/06/2009 kl. 23:01
kilden bruker

stemmer
55

Det korte svaret er at du ikke kan.

Jo lengre, onde svaret er at du liksom kan med noen virkelige nastiness. Og det fungerer bare når de kalles fra en annen funksjon.

Det er to interessante egenskaper tilgjengelig for deg som kan hjelpe

arguments.callee innringer

for fn å gjøre noe som dette:

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

Hva arguments.callee.caller.toString (). Kamp (..) [1] gjør er å se etter den Showme blir kalt i funksjonen kaller det og skriver det og dens verdi.

Men dette er fortsatt ganske begrenset, fordi det vil bare treffe den første samtalen av Showme (x). Så hvis det er to samtaler til det, vil det ikke fungere.

Men det var moro å spille med disse uforståelige ting.

Svarte 17/06/2009 kl. 23:15
kilden bruker

stemmer
1

Ikke sikker på at du kan direkte få det du ønsker fra Javascript, siden variabelnavnet ikke blir gjennomført rundt med verdien den refererer til (tenk på variabelnavn som identifikatorer bare kompilatoren vet om, men som blir kastet bort under kjøring).

Du kan imidlertid gjøre noe litt annerledes som gjør det mulig for passerer rundt navngitte argumenter. Lag en anonym objekt og pass på at din funksjon:

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" } )

For iteraobjektegenskaper, jeg har en tendens til å foretrekke en funksjonell stil, som i:

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" } )
Svarte 17/06/2009 kl. 23:16
kilden bruker

stemmer
2

Du kan lage en hash og pass på at i:

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

Dette betyr ikke nødvendigvis vise navnet på variabelen, men det tillater for nøkkelverdi-par, som kan være mer til poenget med det du trenger.

Svarte 17/06/2009 kl. 23:19
kilden bruker

stemmer
4

Jeg visste allerede at jeg kunne passere i et objekt:

{a:"this is a"}

hvor en er navnet på variabelen, men jeg virkelig ønsker å bare passere i en variabel eller navnet på en variabel (en eller "a") og la funksjonen liksom finne navnet på variabelen og dens verdi.

Grunnen til at jeg ønsker å gjøre dette litt rare er at jeg skriver en debug print rutine. Hvis jeg kaller det slik:

var x = "some string";
say(x);

eller

say("x");

Jeg vil at det skal skrives ut noe sånt som:

X (string) = some string

Jeg kan ganske sikkert finne den typen en variabel gått, og så jeg vet hvordan å skrive den ut, men jeg virkelig ønsker å prøve å unngå redunancy for å måtte kalle det slik:

say("x", x);

som er det jeg må gjøre nå.

Hva synes nesten fungere er OrbMan svar. Jada, eval er ond , men jeg tror det er OK her fordi det er bare for en debug verktøy og vil ikke være i den publiserte kode. Jeg har gjort en liten test rutine av min egen ved hjelp av denne løsningen:

var x = "this is x";

function say(a) {
   alert(a + " = " + eval(a));

}

say("x");

og det fungerer, men bare hvis X er global . Dette fungerer ikke:

function wrapper() {

   var x = "this is x";
   say("x");

}

Så dette er løsningen nære, men siden jeg bruker nesten ingen Globale variabler, er dette ikke kommer til å fungere. Darn, det er såååå nær. Det jeg tror jeg trenger er "anrop ved navn" i stedet for "etter verdi" eller "med referanse". Og jeg trenger en funksjon som vil fungere om det blir kalt fra en annen funksjon eller ikke.

Siden jeg har satt i en god del timer på dette selv, å stille spørsmålet her var en handling av desperasjon, jeg er nødt til å konkludere med at det egentlig ikke er noen måte å gjøre dette. Shucks.

Til alle som svarte, takk for all hjelp.

Svarte 18/06/2009 kl. 17:43
kilden bruker

stemmer
1

Nedenstående kode er omtrent det beste du kan gjøre. Dessverre lokale variablene i en funksjon er egenskaper ved den skjulte Call objektet slik at de ikke kan nås fra Javascript som window [a] hvor a er en egenskap av vinduet objekt.

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()
Svarte 12/07/2011 kl. 00:01
kilden bruker

stemmer
2

Dette er hva jeg bruker for feilsøking. Ingen globale variabler, ingen eval, ingen arguments.callee eller 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;
}());

For de som lurer på hvorfor du ønsker å gjøre dette, det er bare en måte å effektivt logge flere variabler sammen med navnene deres.

Hvis du ønsker å kunne logge nestede medlemmer, som i Module.debug.call(obj, 'hair.fluffiness'), kan du endre funksjonen slik:

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);
    }
};

Dessverre kan jeg ikke finne noen måte å effektivt logge flere private variabler som ikke er medlemmer av et objekt, for eksempel var roll = 3, value = 4; Module.debug.call(???);

Svarte 15/08/2012 kl. 20:21
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more