Konversi string ke nama variabel dalam JavaScript

260

Saya sudah mencari solusi, tetapi tidak dapat menemukannya.

Saya memiliki variabel yang dipanggil onlyVideo.

"onlyVideo"string dilewatkan ke fungsi. Saya ingin mengatur variabel onlyVideodi dalam fungsi sebagai sesuatu. Bagaimana saya bisa melakukan itu?

(Ada sejumlah variabel yang dapat dipanggil ke dalam fungsi, jadi saya membutuhkannya untuk bekerja secara dinamis, bukan ifpernyataan yang dikodekan dengan keras .)

Sunting: Mungkin ada cara yang lebih baik untuk melakukan apa yang Anda coba lakukan. Saya menanyakan hal ini sejak awal dalam petualangan JavaScript saya. Lihat cara kerja objek JavaScript.

Pengenalan sederhana:

// 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
sumber
5
Untuk apa Anda menggunakan ini? Apakah Anda benar-benar yakin harus menyetelnya ke variabel lokal normal, dan Object (Hash) tidak akan berfungsi?
Dogbert
mmm ... Saya masih tidak mengerti mengapa Anda ingin melakukan ini di dunia dengan array. Bagaimanapun, beberapa kode dan penjelasan Anda akan sangat membantu.
Kevin Chavez
saya pikir kita perlu lebih detail tentang apa tujuan akhir Anda
mcgrailm

Jawaban:

281

Jika itu adalah variabel global maka window[variableName] atau dalam kasus Anda window["onlyVideo"]harus melakukan trik.

ingo
sumber
35
Bahkan jika tidak global, Anda dapat mengaksesnya seperti itu pada scope[property]atau bahkanthis[property]
Wojciech Bednarski
7
@WojciechBednarski: Jangan bingung ruang lingkup dan konteks. thisadalah konteks, apa yang ditunjukkan tergantung pada bagaimana fungsi dipanggil. Di JS, 50% dari waktu thisadalah windowkecuali Anda mengaktifkan mode ketat dan thismenjadi undefineddan akan melempar kesalahan. Lingkup adalah sesuatu yang sama sekali berbeda dan itu bukan objek (kecuali ruang lingkup global yang dicerminkan oleh windowobjek)
slebetman
3
Tidak bekerja di WebWorkers( di mana selfmerujuk ke lingkup global, seperti halnya di browser, di mana itu sama dengan window) dan Node.js, di mana globalvariabel yang Anda inginkan. Dan itu lebih baru bekerja dengan cakupan lokal, seperti fungsi tubuh.
Tomáš Zato - Reinstate Monica
adakah di sana untuk mendefinisikan constmenggunakan metode ini?
toing_toing
165

Javascript memiliki eval()fungsi untuk acara-acara seperti itu:

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

Sunting: Maaf, saya pikir saya terlalu cepat membaca pertanyaan. Ini hanya akan membuat Anda variabel, untuk mengaturnya Anda perlu

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

atau jika menggunakan string:

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

Tapi saya membayangkan ada cara yang lebih tepat untuk mencapai apa yang Anda cari? Saya tidak berpikir eval () adalah sesuatu yang Anda benar-benar ingin gunakan kecuali ada alasan bagus untuk itu. eval ()

goggin13
sumber
3
Ya saya akan pergi dengan ini daripada menggunakan jendela (ini memiliki beberapa peringatan)
ingo
12
Mengapa satu eval()jawaban diturunkan untuk dihapus, dan jawaban ini dibatalkan?
BoltClock
4
@ goggin Anda harus menguji ulang argumen untuk memastikan bahwa itu adalah nama yang valid. Hanya menghindari argumen tanpa mengeceknya terlebih dahulu tidak aman.
Šime Vidas
16
Ini adalah satu-satunya jawaban realistis untuk pertanyaan itu. Hanya karena itu melibatkan eval "eeeeevil" tidak membuatnya kurang benar. Javascript tidak memiliki variabel variabel (seperti $$ varname di php) jadi ini adalah satu-satunya jawaban. Menggunakan window[varname]memiliki efek samping dari memperkenalkan variabel global, yang mungkin tidak diinginkan. @ Shaz, saya rasa Anda tidak memberikan cukup banyak penerjemah JS modern. Mereka sangat cepat, dan parsing dan menjalankan operasi penugasan satu baris sederhana tidak akan melonjak penggunaan CPU siapa pun asalkan tidak dilakukan dalam timer 1ms atau loop ketat.
MooGoo
2
@TheParamagneticCroissant Orang-orang yang bersemangat tentang perawatan kode. Mereka yang hanya menghargai waktu dan uang tidak.
Jimbo
41

Sejauh eval vs solusi variabel global ...

Saya pikir ada keuntungan untuk masing-masing tetapi ini benar-benar dikotomi yang salah. Jika Anda paranoid dari namespace global, buat namespace sementara & gunakan teknik yang sama.

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

tempNamespace[myString] = 5;

Cukup yakin Anda kemudian dapat mengakses sebagai tempNamespace.myVarProperty (sekarang 5), menghindari menggunakan jendela untuk penyimpanan. (Tali juga bisa dimasukkan langsung ke dalam kurung)

jm0
sumber
Sedikit refactor kode Anda untuk membuat inline var tempNamespace = {["myVarProperty"] yang sama: "Pasti hanya video"};
Tioma
1
Ini adalah solusi yang sangat bagus - sepertinya eval () harus dihindari kecuali benar-benar diperlukan, solusi yang sangat elegan di sini.
skwidbreth
Dimulai dengan kumpulan dokumen.body.getElementsByTagName ('*') mudah untuk menemukan semua elemen yang memiliki atribut 'id' dan membuat variabel untuk nilai objek elemen masing-masing dalam objek global 'id'. Kemudian Anda dapat merujuk ke <div id = container> dalam JavaScript sebagai 'id.container'. Begitu mudah!
David Spector
15
var myString = "echoHello";

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

echoHello();

Katakan tidak pada eval jahat . Contoh di sini: https://jsfiddle.net/Shaz/WmA8t/

Shaz
sumber
3
Jadikan ini bekerja pada lingkup lokal dan saya akan menghapus downvote.
Tomáš Zato - Reinstate Monica
@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw
@richmondwang thisbukan referensi ke lingkup lokal tetapi ke objek yang terikat fungsi selama panggilan.
Tomáš Zato - Reinstate Monica
8

Anda dapat mengakses objek jendela sebagai array asosiatif dan mengaturnya seperti itu

window["onlyVideo"] = "TEST";
document.write(onlyVideo);
Eric Conner
sumber
8

Metode window ['variabelName'] HANYA berfungsi jika variabel didefinisikan dalam lingkup global. Jawaban yang benar adalah "Refactor". Jika Anda dapat memberikan konteks "Objek" maka solusi umum yang mungkin ada, tetapi ada beberapa variabel yang tidak dapat diselesaikan fungsi global berdasarkan pada cakupan variabel.

(function(){
    var findMe = 'no way';
})();
Lance Caraccioli
sumber
6

Jika Anda mencoba mengakses properti objek, Anda harus mulai dengan cakupan windowdan menelusuri setiap properti objek hingga Anda mendapatkan yang Anda inginkan. Dengan asumsi yang a.b.ctelah didefinisikan di tempat lain dalam skrip, Anda dapat menggunakan yang berikut:

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

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

Ini akan bekerja untuk mendapatkan properti dari objek apa pun, tidak peduli seberapa dalam itu.


sumber
Contoh Anda keren. Saya perhatikan bahwa jika saya gunakan namesebagai nama variabel, contoh Anda gagal, tetapi berfungsi dengan nama variabel lainnya. Ini mungkin ada hubungannya dengan objek Window yang sudah memiliki namevariabel. Juga, termasuk .valuemetode yang menyebabkan kegagalan. Kemampuan untuk menafsirkan variabel objek bersarang mendalam adalah apa yang saya cari dan metode Anda menunjukkan arah yang baik. Terima kasih.
Theo
Tidak masalah. Jawabannya lebih untuk menunjukkan konsep daripada menjadi copy / paste jawaban (seperti kebanyakan jawaban di sini pada SO saya pikir)
1
Respons SO bahkan lebih baik ketika Anda dapat menghabiskan waktu untuk memperbaikinya daripada memperbaikinya. ;-)
Theo
Tidak berfungsi:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14
5

Anda bisa melakukan ini

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

Eliyah Sundström
sumber
0

Itu bisa dilakukan seperti ini

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

Yunzen
sumber
0

Kode berikut memudahkan untuk merujuk ke masing-masing DIV dan elemen HTML lainnya dalam JavaScript. Kode ini harus dimasukkan tepat sebelum tag, sehingga semua elemen HTML telah terlihat. Itu harus diikuti oleh kode JavaScript Anda.

// 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
sumber
0

biarkan saya membuatnya lebih jelas

function changeStringToVariable(variable, value){
window[variable]=value
}
changeStringToVariable("name", "john doe");
console.log(name);
//this outputs: john doe
let file="newFile";
changeStringToVariable(file, "text file");
console.log(newFile);
//this outputs: text file
Kalidan
sumber
1
Selamat Datang di Stack Overflow! Meskipun kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu untuk meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan berikan indikasi tentang batasan dan asumsi apa yang berlaku.
Daniil