Javascript verwendet Variable als Objektname

87

Ich möchte den Wert einer Variablen verwenden, um auf ein Objekt zuzugreifen.

Angenommen, ich habe ein Objekt namens myobject.

Ich möchte eine Variable mit diesem Namen füllen und die Variable verwenden, um auf das Objekt zuzugreifen.

Beispiel:

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

Antworten:

122

Global:

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

console.log(this[anObjectName]);

Global: v2

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

console.log(myObject)

Lokal: 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);
})();

Lokal: v2

(function() {  
    var scope = this;

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

    console.log(scope.myObject.value);    
}).call({});
Shaz
quelle
@Shaz - beide dieser Referenz der gleiche Umfang tatsächlich ;-) (vorausgesetzt , sie in einem Browser ausgeführt werden.) alert(this === window).
Sean Vieira
1
@PeeHaa - Das Local Beispiel setzt eine Variable auf dem windowObjekt aufgerufen , objnamedie dann über verwiesen wird this... Sie ersetzen könnte windowfür thisim zweiten Beispiel , und alles würde immer noch funktionieren. :-)
Sean Vieira
1
@ SeanVieira: Schauen Sie sich das aktualisierte Beispiel an. Hoffentlich funktioniert das jetzt richtig.
Shaz
1
@Shaz - arguments.calleeist veraltet, aber dennoch eine sehr clevere Implementierung - und verschmutzt nicht den globalen Geltungsbereich. +1
Sean Vieira
1
Möglicherweise wird der globale Bereich nicht verschmutzt, es wird jedoch ein Objekt erstellt, das von jedem Aufruf der Funktion gemeinsam genutzt wird. Ihre Funktion ist objnameeine Eigenschaft der Funktion selbst. Es kann für rekursive Funktionen fehlschlagen. Ich bin mir nicht sicher, wie dies in der realen Welt verwendet werden kann.
Juan Mendes
25

Verwenden Sie eine eckige Klammer um den Variablennamen.

var objname = 'myobject';
{[objname]}.value = 'value';
Vaishali Venkatesan
quelle
6
Dies ist perfekt und einfach und sollte die beste Antwort sein.
Brad
4
Dies löst eine Ausnahme aus: SyntaxError: erwarteter Ausdruck, bekam '.'. Es funktioniert nicht; warum so viele positive Stimmen?
Lovro
8

Ist es eine globale Variable? Wenn ja, sind diese tatsächlich Teil des windowObjekts, sodass Sie dies tun können window[objname].value.

Wenn es sich um eine lokale Funktion handelt, gibt es meines Erachtens keinen guten Weg, um das zu tun, was Sie wollen.

JW.
quelle
7

Das Objekt ist in einem bestimmten Bereich vorhanden, sodass Sie fast immer über diese Syntax auf die Variable zugreifen können:

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

Der einzige Ort, an dem dies schwierig wird, ist, wenn Sie sich in einem geschlossenen Bereich befinden und Zugriff auf eine lokale Variable der obersten Ebene wünschen. Wenn Sie so etwas haben:

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

Sie können dies umgehen, indem Sie evalstattdessen auf die aktuelle Bereichskette zugreifen ... aber ich empfehle es nicht, es sei denn, Sie haben viele Tests durchgeführt und wissen , dass dies der beste Weg ist, um Dinge zu erledigen .

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

Ihre beste Wette ist , einen Verweis auf einen Namen haben , in einem immer-going-to-be-es - Objekt (wie thisim globalen Bereich oder ein privates Top-Level - Variable in einem lokalen Bereich) und setzte alles anderes drin.

So:

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]
})();
Sean Vieira
quelle
6

Sie könnten verwenden eval:

eval(variablename + ".value = 'value'");
Midas
quelle
Wird nicht evalberücksichtigt evil? Wenn nicht, könnte ich es benutzen. Weil es momentan global ist, aber ich wollte es in eine Funktion verschieben, um Sachen aufzuräumen.
PeeHaa
1
Lol. Wenn der Variablenname aus Benutzereingaben stammt, stellen Sie sicher, dass Sie ihn validieren, damit er keinen JS-Code enthält, der ausgeführt werden evalkann.
Midas
1
Dies ist evalmeiner Meinung nach eine der wenigen legitimen Verwendungen von . Wir müssen jedoch sicherstellen, dass die Variable sauber ist.
Levi Morrison
2
Ja, das ist kein wirkliches Problem. Aber schauen Sie sich die Antwort von Shaz an. Ich denke, das ist eine sauberere Lösung.
Midas
2
@PeeHaa: Wenn Sie überlegen, es zu verschieben, warum verschieben Sie es nicht in eine Eigenschaft eines bekannten Objekts, damit Sie so etwas tun können myVar[objname].value?
JW.
5

Sie können dies im Allgemeinen nicht tun, außer im Fensterbereich, in dem Sie schreiben können window[objname].value = 'value';

Neil
quelle
3

Ich denke, Shaz 'Antwort für lokale Variablen ist schwer zu verstehen, obwohl sie für nicht rekursive Funktionen funktioniert. Hier ist ein anderer Weg, den ich für klarer halte (aber es ist immer noch seine Idee, genau dasselbe Verhalten). Es wird auch nicht dynamisch auf die lokalen Variablen zugegriffen, sondern nur auf die Eigenschaft der lokalen Variablen.

Im Wesentlichen wird eine globale Variable verwendet (die an das Funktionsobjekt angehängt ist).

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

Dies entspricht im Wesentlichen dem Erstellen einer globalen Datei zum Speichern der Variablen, sodass Sie als Eigenschaft darauf zugreifen können. Ein Global zu erstellen, um dies zu tun, ist so ein Hack.

Hier ist ein sauberer Hack, der keine globalen Variablen erstellt, sondern stattdessen eine lokale Variable verwendet.

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

Siehe Javascript: Zeichenfolge als Objektreferenz interpretieren?

Juan Mendes
quelle
0

Stellen Sie bei Verwendung des Fensters [Objektname] sicher, dass es sich bei dem Objektnamen um globale Variablen handelt. Andernfalls wird irgendwann funktionieren und manchmal fehlschlagen. window [objname] .value.

lyon819
quelle
0

Wenn sich das Objekt in einem Namespace befindet, z. Company.Module.Components.FooSie können diese Funktion verwenden:

CoffeeScript:

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

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

Dann können Sie ein neues Objekt erstellen oder was auch immer tun. Beachten Sie die Eltern durch.

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

Diese Idee stammt aus einer ähnlichen Frage: Wie man eine JavaScript-Funktion ausführt, wenn ich ihren Namen als Zeichenfolge habe

Gemeinschaft
quelle
0

Eine der Herausforderungen, die ich mit den Antworten hatte, war die Annahme, dass das Objekt eine einzelne Ebene war. Beispielsweise,

const testObj = { testKey: 'testValue' }
const refString = 'testKey';
const refObj = testObj[refString];

funktioniert gut, aber

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testKey.level2Key';
const refObj = testObj[refString];

funktioniert nicht.

Am Ende habe ich eine Funktion für den Zugriff auf mehrstufige Objekte erstellt:

objVar(str) {
    let obj = this;
    const parts = str.split('.');
    for (let p of parts) {
        obj = obj[p];
    }
    return obj;
}

Im zweiten Szenario kann ich dann die Zeichenfolge an diese Funktion übergeben, um das gesuchte Objekt zurückzugewinnen:

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testObj.testKey.level2Key';
const refObj = objVar[refString];
Mitch Parker
quelle
0

Sie können eine Objekteigenschaft folgendermaßen festlegen:

var obj = {};
obj.whateverVarName = 'yourVal';
console.log(obj);

ThisisFish
quelle
0

Wenn Sie die Liste der möglichen Variablennamen bereits kennen, erstellen Sie ein neues Objekt (iconObj), dessen Eigenschaftsname mit den Objektnamen identisch ist. Im folgenden Beispiel enthält die Variable iconLib zwei Zeichenfolgenwerte, entweder 'ZondIcons' oder 'MaterialIcons'. . propertyName ist die Eigenschaft von ZondIcons oder MaterialsIcon.

   const iconObj = {
    ZondIcons,
    MaterialIcons,
  }
  const objValue = iconObj[iconLib][propertyName]
Sumer
quelle
0
let players = [];
players[something] = {};
players[something].somethingElse = 'test';
console.log(players); 

-> [etwas: {etwasElse: 'test'}];

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

var device = 'test';

console.log(micro[device]);
Alfonsoolavarria
quelle