2011-05-21 4 views
72

Je veux utiliser la valeur d'une variable pour accéder à un objet.Javascript use variable comme nom d'objet

Disons que j'ai un objet nommé myobject.

Je souhaite remplir une variable avec ce nom et utiliser la variable pour accéder à l'objet.

Exemple:

var objname = 'myobject'; 
{objname}.value = 'value'; 

Répondre

100

mondial:

myObject = { value: 0 }; 
anObjectName = "myObject"; 
this[anObjectName].value++; 

console.log(this[anObjectName]); 

mondiale: v2

var anObjectName = "myObject"; 
this[anObjectName] = "myvalue" 

console.log(myObject) 

Local: v1

(function() { 
    var scope = this; 

    if (scope != arguments.callee) { 
     arguments.callee.call(arguments.callee); 
     return false; 
    } 

    scope.myObject = { value: 0 }; 
    scope.anObjectName = "myObject"; 
    scope[scope.anObjectName].value++; 

    console.log(scope.myObject.value); 
})(); 

locale: v2

(function() { 
    var scope = this; 

    scope.myObject = { value: 0 }; 
    scope.anObjectName = "myObject"; 
    scope[scope.anObjectName].value++; 

    console.log(scope.myObject.value);  
}).call({}); 
+0

@Shaz: Ha! Comment intelligent ... – PeeHaa

+0

@Shaz - les deux font référence à la même portée en fait ;-) (En supposant qu'ils sont exécutés dans un navigateur.) 'Alert (this === window)'. –

+0

@Sean: Ils sont. Et ils font? – PeeHaa

6

Est-il une variable globale? Si oui, ils font partie de l'objet window, donc vous pouvez faire window[objname].value.

Si c'est local à une fonction, je ne pense pas qu'il y ait un bon moyen de faire ce que vous voulez.

5

Vous ne pouvez pas faire cela en général, sauf à la portée de la fenêtre, où vous pouvez écrire window[objname].value = 'value';

5

Vous pouvez utiliser eval:

eval(variablename + ".value = 'value'"); 
+0

Est-ce que 'eval' n'est pas considéré comme 'mal'? Sinon, je pourrais l'utiliser. Parce que c'est un global en ce moment mais je voulais le déplacer dans une fonction pour nettoyer les choses. – PeeHaa

+1

Lol. Si le nom de la variable provient d'une entrée utilisateur, assurez-vous de la valider, afin qu'elle ne contienne aucun code JS que 'eval' puisse exécuter. – Midas

+0

@Midas: il ne vient pas directement de l'entrée de l'utilisateur. Mais à partir du contenu de données d'un élément HTML. Ce que l'utilisateur peut bien sûr manipuler. Cependant, je ne vois pas ce qui est si mauvais si l'utilisateur peut exécuter son propre code JS. Il est seulement exécuté sur le client ou est-ce que je manque quelque chose? – PeeHaa

7

L'objet existe dans une certaine portée, de sorte que vous pouvez accéder à presque toujours la variable via cette syntaxe :

var objname = "myobject"; 
containing_scope_reference[objname].some_property = 'some value'; 

Le seul endroit où cela devient délicat est lorsque vous êtes dans une portée fermée et que vous voulez accéder à une variable locale de premier niveau. Lorsque vous avez quelque chose comme ceci:

(function(){ 
    var some_variable = {value: 25}; 
    var x = "some_variable"; 
    console.log(this[x], window[x]); // Doesn't work 
})(); 

Vous peut se déplacer qu'en utilisant eval au lieu d'accéder à la chaîne de portée actuelle ... mais je ne le recommande pas, sauf si vous avez fait beaucoup de tests et savez que c'est la meilleure façon de faire les choses.

(function(){ 
    var some_variable = {value: 25}; 
    var x = "some_variable"; 
    eval(x).value = 42; 
    console.log(some_variable); // Works 
})(); 

Votre meilleur pari est d'avoir une référence à un nom dans un toujours en cours à être-là l'objet (comme this dans la portée globale ou une variable de haut niveau privé dans une portée locale) et mettre tout d'autre part là-bas.

Ainsi:

var my_outer_variable = {}; 
var outer_pointer = 'my_outer_variable'; 
// Reach my_outer_variable with this[outer_pointer] 
// or window[outer_pointer] 

(function(){ 
    var my_inner_scope = {'my_inner_variable': {} }; 
    var inner_pointer = 'my_inner_variable'; 
    // Reach my_inner_variable by using 
    // my_inner_scope[inner_pointer] 
})(); 
3

Je pense que la réponse de Shaz pour les variables locales est difficile à comprendre, bien que cela fonctionne pour les fonctions non récursives. Voici une autre façon que je pense que c'est plus clair (mais c'est toujours son idée, exactement le même comportement). Il n'accède pas dynamiquement aux variables locales, juste la propriété de la variable locale.

Essentiellement, il utilise une variable globale (attachée à l'objet de la fonction)

// Here's a version of it that is more straight forward. 
function doIt() { 
    doIt.objname = {}; 
    var someObject = "objname"; 
    doIt[someObject].value = "value";  
    console.log(doIt.objname); 
})(); 

Ce qui est essentiellement la même chose que la création d'un globale pour stocker la variable, vous pouvez y accéder en tant que propriété. Créer un global pour le faire est un tel hack.

Voici un hack plus propre qui ne crée pas de variables globales, il utilise à la place une variable locale.

function doIt() { 
    var scope = { 
    MyProp: "Hello" 
    }; 
    var name = "MyProp"; 
    console.log(scope[name]); 
} 

Voir Javascript: interpret string as object reference?

0

Lorsque vous utilisez la fenêtre [nom_objet], s'il vous plaît assurez-vous que nomobj variables globales. Sinon, fonctionnera parfois et échouera parfois. window [objname] .value.

0

Si l'objet est dans un espace de noms, par exemple. Company.Module.Components.Foo vous pouvez utiliser cette fonction:

CoffeeScript:

objByName: (name, context = window) -> 
    ns = name.split "." 
    func = context 
    for n, i in ns 
     func = func[n] 
    return func 

Entraîné Js:

objByName: function(name, context) { 
    var func, i, n, ns, _i, _len; 
    if (context == null) { 
    context = window; 
    } 
    ns = name.split("."); 
    func = context; 
    for (i = _i = 0, _len = ns.length; _i < _len; i = ++_i) { 
    n = ns[i]; 
    func = func[n]; 
    } 
    return func; 
} 

Ensuite, vous pouvez créer un nouvel objet ou faire tout. Notez les parenthèses à travers.

var o = new (objByName('Company.Module.Components.Foo')) 
objByName('some.deeply.nested.object').value 

Cette idée est empruntée à la même question: How to execute a JavaScript function when I have its name as a string

-1
var micro=[{'test':'hello'}]; 

var device = 'test'; 

console.log(micro[device]); 
3

Utiliser le support carré autour de nom de variable.

var objname = 'myobject'; 
{[objname]}.value = 'value';