2009-02-28 26 views
18

Si desea utilizar las funciones globales y variables dinámicamente puede utilizar:¿Cómo puedo acceder al ámbito local dinámicamente en javascript?

window[functionName](window[varName]); 

¿Es posible hacer lo mismo para las variables en el ámbito local?

Este código funciona correctamente pero actualmente usa eval y estoy tratando de pensar en qué otra manera hacerlo.

var test = function(){ 
    //this = window 
    var a, b, c; //private variables 

    var prop = function(name, def){ 
     //this = window 
     eval(name+ ' = ' + (def.toSource() || undefined) + ';');  

     return function(value){ 
      //this = test object 
      if (!value) { 
       return eval('(' + name + ')'); 
      } 
      eval(name + ' = value;') 
      return this; 
     }; 

    }; 

    return { 
     a:prop('a', 1), 
     b:prop('b', 2), 
     c:prop('c', 3), 
     d:function(){ 
      //to show that they are accessible via to methods 
      return [a,b,c]; 
     } 
    }; 
}(); 

>>>test 
Object 
>>>test.prop 
undefined 
>>>test.a 
function() 
>>>test.a() 
1 //returns the default 
>>>test.a(123) 
Object //returns the object 
>>>test.a() 
123 //returns the changed private variable 
>>>test.d() 
[123,2,3] 
+1

Entiendo por qué estaba confundido ahora, es porque está nombrando las variables abc ASÍ COMO los nombres para la devolución. Deberías cambiar esos nombres, eso es lo que me estaba confundiendo. De todos modos, mejores respuestas que las mías han aparecido, así que voy a diferir a la media luna en este momento. –

+0

@Gothdo La pregunta a la que se vincula es preguntar algo diferente. Las variables a las que intenta acceder son variables globales. La respuesta aceptada también usa variables globales. La pregunta vinculada debe ser cambiada. – Annan

Respuesta

6

No, como crescentfresh dicho. A continuación encontrará un ejemplo de cómo implementar sin eval, pero con un objeto privado interno.

var test = function() { 
    var prv={ }; 
    function prop(name, def) { 
    prv[name] = def; 
    return function(value) { 
     // if (!value) is true for 'undefined', 'null', '0', NaN, '' (empty string) and false. 
     // I assume you wanted undefined. If you also want null add: || value===null 
     // Another way is to check arguments.length to get how many parameters was 
     // given to this function when it was called. 
     if (typeof value === "undefined"){ 
     //check if hasOwnProperty so you don't unexpected results from 
     //the objects prototype. 
     return Object.prototype.hasOwnProperty.call(prv,name) ? prv[name] : undefined; 
     } 
     prv[name]=value; 
     return this; 
    } 
    }; 

    return pub = { 
    a:prop('a', 1), 
    b:prop('b', 2), 
    c:prop('c', 3), 
    d:function(){ 
     //to show that they are accessible via two methods 
     //This is a case where 'with' could be used since it only reads from the object. 
     return [prv.a,prv.b,prv.c]; 
    } 
    }; 
}(); 
+0

¿Qué hay de enumerar las variables locales en la función en sí? En otras palabras, como eval, pero cuando no sabes lo que son los locales ... – Michael

+0

@Michael Lo siento, pero no entiendo a qué te refieres. ¿Podría dar un ejemplo? ¿O tal vez incluso escribir tu propia respuesta? – some

+0

no tengo una respuesta, y todo lo que he leído parece sugerir que es imposible ... las variables globales en un navegador se pueden enumerar con algo como 'para (i en ventana)'; Sería bueno si eso fuera posible para los locales en una función. – Michael

2

Espero que no simplifique demasiado, pero ¿qué pasa con algo tan simple como usar un objeto?

var test = { 
    getValue : function(localName){ 
     return this[localName]; 
    }, 
    setValue : function(localName, value){ 
     return this[localName] = value; 
    } 
}; 

>>> test.a = 123 
>>> test.getValue('a') 
123 
>>> test.a 
123 

>>> test.setValue('b', 999) 
999 
>>> test.b 
999 
+0

Si solo va a acceder directamente a las variables locales del objeto, ¿para qué sirve definir un getter o setter? –

+0

No hay uno. Acabo de agregar eso para que el uso sea idéntico al ejemplo de Annan. Estoy de acuerdo, sería completamente estúpido en la práctica. –

+0

El motivo del código es emular la forma en que getters y setters funcionan de forma cruzada. Por lo tanto, mi código original era incorrecto (ahora se arregló) ya que las variables prop() creadas no estaban disponibles para el resto del objeto. Tu camino permite el acceso directo y la manipulación de propiedades. – Annan

7

Para responder a su pregunta, no, no hay manera de hacer las operaciones de búsqueda variable dinámica en un ámbito local sin necesidad de utilizar eval().

La mejor alternativa es hacer que su "alcance" sea solo un objeto normal [literal] (es decir, "{}"), y pegar sus datos allí.

Cuestiones relacionadas