Konwertuj ciąg na nazwę zmiennej w JavaScript

260

Szukałem rozwiązań, ale nie mogłem znaleźć żadnej takiej pracy.

Mam zmienną o nazwie onlyVideo.

"onlyVideo"ciąg zostaje przekazany do funkcji. Chcę ustawić zmienną onlyVideowewnątrz funkcji jako coś. Jak mogę to zrobić?

(Istnieje wiele zmiennych, które można wywoływać w funkcji, więc potrzebuję jej do pracy dynamicznej, a nie ifinstrukcji zakodowanych na stałe).

Edycja: Prawdopodobnie jest lepszy sposób na robienie tego, co próbujesz zrobić. Zapytałem o to na początku mojej przygody z JavaScriptem. Sprawdź, jak działają obiekty JavaScript.

Proste wprowadzenie:

// create JavaScript object
var obj = { "key1": 1 };

// assign - set "key2" to 2
obj.key2 = 2;

// read values
obj.key1 === 1;
obj.key2 === 2;

// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;

// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;
switz
źródło
5
Do czego tego używasz? Czy jesteś absolutnie pewien, że musisz ustawić normalną zmienną lokalną, a obiekt (skrót) nie będzie działał?
Dogbert
mmm ... Nadal nie rozumiem, dlaczego chcesz to robić w świecie z tablicami. W każdym razie część twojego kodu i wyjaśnień bardzo by pomogła.
Kevin Chavez,
myślę, że potrzebujemy więcej szczegółów na temat twojego ostatecznego celu
mcgrailm,

Odpowiedzi:

280

Jeśli jest to zmienna globalna, to window[variableName] lub w twoim przypadku window["onlyVideo"]powinno wystarczyć .

ingo
źródło
35
Nawet jeśli nie globalny, możesz uzyskać do niego dostęp scope[property]nawet przezthis[property]
Wojciech Bednarski
7
@WojciechBednarski: Nie myl zakresu i kontekstu. thisto kontekst, na który wskazuje, zależy od tego, jak wywoływana jest funkcja. W JS 50% czasu thisjest możliwe, windowchyba że włączysz tryb ścisły i staniesz thissię undefinedi wyrzuci błąd. Zakres jest czymś zupełnie innym i nie jest obiektem (z wyjątkiem zasięgu globalnego, który jest dublowany przez windowobiekt)
slebetman
3
Nie działa w WebWorkers(gdzie selfodnosi się do zasięgu globalnego, podobnie jak w przeglądarce, gdzie jest równy window) i Node.js, gdzie globaljest zmienna, którą chcesz. Nowsze działa z lokalnymi zakresami, takimi jak treść funkcji.
Tomáš Zato - Przywróć Monikę
czy w ogóle można zdefiniować constużycie tej metody?
toing_toing
165

Javascript ma eval()funkcję na takie okazje:

function (varString) {
  var myVar = eval(varString);
  // .....
}

Edycja: Przepraszam, myślę, że zbyt szybko odrzuciłem pytanie. Otrzymasz tylko zmienną, aby ustawić ją, której potrzebujesz

function SetTo5(varString) {
  var newValue = 5;
  eval(varString + " = " + newValue);
}

lub jeśli używasz ciągu:

function SetToString(varString) {
  var newValue = "string";
  eval(varString + " = " + "'" + newValue + "'");
}

Ale wyobrażam sobie, że istnieje bardziej odpowiedni sposób na osiągnięcie tego, czego szukasz? Nie sądzę, że eval () jest czymś, czego naprawdę chcesz używać, chyba że istnieje ku temu dobry powód. eval ()

goggin13
źródło
3
Tak, wolałbym raczej to, niż korzystać z okna (ma pewne zastrzeżenia)
ingo
12
Dlaczego jedna eval()odpowiedź została uznana za skreśloną, a ta pozytywna?
BoltClock
4
@goggin Powinieneś ponownie przetestować argument, aby upewnić się, że jest to poprawna nazwa. Samo sprawdzenie argumentu bez uprzedniego sprawdzenia go jest absurdalnie niepewne.
Šime Vidas,
16
To jedyna realistyczna odpowiedź na pytanie. To, że dotyczyło to ewaluacji „eeeeevil”, nie czyni jej mniej prawdziwą. JavaScript nie ma zmiennych zmiennych (takich jak $$ varname w php), więc to naprawdę jedyna odpowiedź. Używanie window[varname]ma efekt uboczny wprowadzania zmiennych globalnych, co może nie być pożądane. @Shaz Nie sądzę, żebyś dał współczesnym tłumaczom JS wystarczający kredyt. Są niezwykle szybkie, a parsowanie i wykonywanie prostej operacji przypisania jednego wiersza nie zwiększy niczyjego użycia procesora, o ile nie odbywa się to w zegarze 1ms lub w ciasnej pętli.
MooGoo,
2
@TheParamagneticCroissant Ludzie, którzy są pasjonatami pielęgnacji kodu. Ci, którzy cenią tylko czas i pieniądze, tego nie robią.
Jimbo
41

W zakresie rozwiązań eval vs. globalne zmienne ...

Myślę, że każda z nich ma swoje zalety, ale tak naprawdę jest to fałszywa dychotomia. Jeśli jesteś paranoikiem globalnej przestrzeni nazw, po prostu utwórz tymczasową przestrzeń nazw i użyj tej samej techniki.

var tempNamespace = {};
var myString = "myVarProperty";

tempNamespace[myString] = 5;

Jestem prawie pewien, że możesz wtedy uzyskać dostęp jako tempNamespace.myVarProperty (teraz 5), unikając używania okna do przechowywania. (Ciąg można również umieścić bezpośrednio w nawiasach)

jm0
źródło
Nieco zmodyfikuj kod, aby utworzyć ten sam inline var tempNamespace = {["myVarProperty"]: „Zdecydowanie tylko wideo”};
Tioma
1
Jest to bardzo dobre rozwiązanie - wydaje się, że należy unikać eval (), chyba że jest to absolutnie konieczne, bardzo eleganckie obejście tutaj.
skwidbreth
Począwszy od kolekcji document.body.getElementsByTagName („*”) łatwo jest znaleźć wszystkie elementy posiadające atrybut „id” i utworzyć zmienną dla wartości obiektu każdego z nich w obiekcie globalnym „id”. Następnie możesz odwołać się do <div id = container> w JavaScript jako „id.container”. Tak łatwo!
David Spector
15
var myString = "echoHello";

window[myString] = function() {
    alert("Hello!");
}

echoHello();

Powiedz nie ewangelii zła . Przykład tutaj: https://jsfiddle.net/Shaz/WmA8t/

Shaz
źródło
3
Zrób to na lokalnym zasięgu, a ja usunę głosowanie.
Tomáš Zato - Przywróć Monikę
@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw
@richmondwang thisnie odnosi się do zasięgu lokalnego, ale do obiektu, do którego funkcja jest przypisana podczas wywołania.
Tomáš Zato - Przywróć Monikę
8

Możesz uzyskać dostęp do obiektu okna jako tablicy asocjacyjnej i ustawić go w ten sposób

window["onlyVideo"] = "TEST";
document.write(onlyVideo);
Eric Conner
źródło
8

Metoda window [„nazwa zmiennej” działa TYLKO, jeśli zmienna jest zdefiniowana w zakresie globalnym. Prawidłowa odpowiedź to „Refaktoryzacja”. Jeśli możesz podać kontekst „obiektowy”, istnieje możliwe ogólne rozwiązanie, ale istnieją pewne zmienne, których żadna funkcja globalna nie mogłaby rozpoznać na podstawie zakresu zmiennej.

(function(){
    var findMe = 'no way';
})();
Lance Caraccioli
źródło
6

Jeśli próbujesz uzyskać dostęp do właściwości obiektu, musisz zacząć od zakresu windowi przejść przez każdą właściwość obiektu, aż dojdziesz do tej, którą chcesz. Zakładając, że a.b.czostał zdefiniowany gdzieś w skrypcie, możesz użyć następujących opcji:

var values = window;
var str = 'a.b.c'.values.split('.');

for(var i=0; i < str.length; i++)
    values = values[str[i]];

Będzie to działać w celu uzyskania właściwości dowolnego obiektu, bez względu na jego głębokość.


źródło
Twój przykład jest fajny. Zauważ, że jeśli użyję namejako nazwy zmiennej, twój przykład zawiedzie, ale działa z innymi nazwami zmiennych. Może to mieć związek z obiektem Window posiadającym już namezmienną. Również włączenie tej .valuemetody spowodowało awarię. Szukam interpretacji głęboko zagnieżdżonych zmiennych obiektowych, a twoja metoda wskazuje dobry kierunek. Dzięki.
Theo
Nie ma problemu. Odpowiedzią jest raczej zademonstrowanie koncepcji niż odpowiedź kopiuj / wklej (jak sądzę, większość odpowiedzi tutaj na SO)
1
Odpowiedzi SO są nawet lepsze, gdy możesz poświęcić czas na ich ulepszanie, a nie na ich naprawianie. ;-)
Theo
Nie działa:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14,
5

Możesz to zrobić w ten sposób

var name = "foo";
var value = "Hello foos";
eval("var "+name+" = '"+value+"';");
alert(foo);

Eliyah Sundström
źródło
0

Można to zrobić w ten sposób

(function(X, Y) {
  
  // X is the local name of the 'class'
  // Doo is default value if param X is empty
  var X = (typeof X == 'string') ? X: 'Doo';
  var Y = (typeof Y == 'string') ? Y: 'doo';
  
  // this refers to the local X defined above
  this[X] = function(doo) {
    // object variable
    this.doo = doo || 'doo it';
  }
  // prototypal inheritance for methods
  // defined by another
  this[X].prototype[Y] = function() {
    return this.doo || 'doo';
  };
  
  // make X global
  window[X] = this[X];
}('Dooa', 'dooa')); // give the names here

// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());

Junzen
źródło
0

Poniższy kod ułatwia odwoływanie się do każdego elementu DIV i innych elementów HTML w JavaScript. Ten kod należy dołączyć tuż przed tagiem, aby wszystkie elementy HTML były widoczne. Po nim powinien znajdować się kod JavaScript.

// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
    {
    thisid = els[i].id;
    if (!thisid)
        continue;
    val=D.getElementById(thisid);
    id[thisid]=val;
    }

// Usage:
id.MyDIV.innerHTML="hello";
David Spector
źródło