Javascript menggunakan variabel sebagai nama objek

91

Saya ingin menggunakan nilai variabel untuk mengakses objek.

Katakanlah saya memiliki sebuah objek bernama myobject.

Saya ingin mengisi variabel dengan nama ini dan menggunakan variabel untuk mengakses objek.

Contoh:

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

Jawaban:

125

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
sumber
@Shaz - keduanya mereferensikan cakupan yang sama ;-) (Dengan asumsi keduanya dijalankan di browser.) alert(this === window).
Sean Vieira
1
@PeeHaa - The Local contoh set variabel pada windowobjek disebut objnameyang kemudian direferensikan melalui this... Anda bisa mengganti windowuntuk thisdi contoh kedua dan semuanya akan masih bekerja. :-)
Sean Vieira
1
@SeanVieira: Lihat contoh yang diperbarui. Semoga ini berfungsi dengan benar sekarang.
Shaz
1
@Shaz - arguments.calleesudah tidak digunakan lagi, namun ini adalah implementasi yang sangat cerdas - dan tidak mengotori cakupan global. +1
Sean Vieira
1
Ini mungkin tidak mencemari ruang lingkup global, tetapi itu membuat objek yang dibagikan oleh setiap pemanggilan fungsi. Fungsi Anda dipegang objnamesebagai properti dari fungsi itu sendiri. Itu bisa gagal untuk fungsi rekursif. Tidak yakin bagaimana ini bisa digunakan di dunia nyata.
Juan Mendes
27

Gunakan tanda kurung siku di sekitar nama variabel.

var objname = 'myobject';
{[objname]}.value = 'value';
Vaishali Venkatesan
sumber
7
Ini sempurna dan sederhana dan harus menjadi jawaban teratas.
Brad
5
Ini memunculkan pengecualian: SyntaxError: ekspresi yang diharapkan, mendapat '.'. Tidak bekerja; mengapa begitu banyak suara positif?
Lovro
9

Apakah ini variabel global? Jika demikian, ini sebenarnya adalah bagian dari windowobjek, jadi Anda bisa melakukannya window[objname].value.

Jika itu lokal untuk suatu fungsi, saya rasa tidak ada cara yang baik untuk melakukan apa yang Anda inginkan.

JW.
sumber
8

Objek ada dalam beberapa cakupan, jadi Anda hampir selalu dapat mengakses variabel melalui sintaks ini:

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

Satu-satunya tempat di mana hal ini menjadi rumit adalah ketika Anda berada dalam cakupan tertutup dan Anda menginginkan akses ke variabel lokal tingkat atas. Ketika Anda memiliki sesuatu seperti ini:

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

Anda dapat menyiasatinya dengan menggunakan evalalih - alih mengakses rantai cakupan saat ini ... tetapi saya tidak merekomendasikannya kecuali Anda telah melakukan banyak pengujian dan Anda tahu bahwa itulah cara terbaik untuk melakukan sesuatu.

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

Taruhan terbaik Anda adalah memiliki referensi ke nama dalam objek yang selalu akan ada (seperti thisdalam lingkup global atau variabel tingkat atas pribadi dalam lingkup lokal) dan meletakkan semua yang lain di sana.

Jadi:

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

Anda bisa menggunakan eval:

eval(variablename + ".value = 'value'");
Midas
sumber
Tidak evaldianggap evil? Jika tidak, saya mungkin akan menggunakannya. Karena ini global sekarang tapi saya ingin memindahkannya ke fungsi untuk membersihkan barang.
PeeHaa
1
Lol. Jika nama variabel berasal dari input pengguna, pastikan Anda memvalidasinya, sehingga tidak berisi kode JS yang evaldapat dieksekusi.
Midas
1
Ini adalah salah satu dari sedikit penggunaan yang sah eval, menurut saya. Kami harus memastikan variabelnya bersih.
Levi Morrison
2
Ya, itu tidak masalah. Tapi lihatlah jawaban dari Shaz. Saya pikir itu solusi yang lebih bersih.
Midas
2
@PeeHaa: Jika Anda sedang mempertimbangkan untuk memindahkannya, mengapa tidak memindahkannya ke properti objek yang diketahui, sehingga Anda dapat melakukan sesuatu seperti itu myVar[objname].value?
JW.
6

Anda tidak dapat melakukan ini secara umum, kecuali pada lingkup jendela, tempat Anda dapat menulis window[objname].value = 'value';

Neil
sumber
4

Saya pikir jawaban Shaz untuk variabel lokal sulit dipahami, meskipun berfungsi untuk fungsi non-rekursif. Inilah cara lain yang menurut saya lebih jelas (tapi itu tetap idenya, perilaku yang sama persis). Ini juga tidak mengakses variabel lokal secara dinamis, hanya properti dari variabel lokal.

Pada dasarnya, ini menggunakan variabel global (dilampirkan ke objek fungsi)

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

Yang pada dasarnya sama dengan membuat global untuk menyimpan variabel, sehingga Anda dapat mengaksesnya sebagai properti. Membuat global untuk melakukan ini adalah peretasan seperti itu.

Inilah peretasan yang lebih bersih yang tidak membuat variabel global, melainkan menggunakan variabel lokal.

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

Lihat Javascript: menafsirkan string sebagai referensi objek?

Juan Mendes
sumber
1

Jika objek ada di beberapa namespace yaitu. Company.Module.Components.FooAnda dapat menggunakan fungsi ini:

CoffeeScript:

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

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

Kemudian Anda dapat membuat objek baru atau melakukan apa pun. Perhatikan tanda kurung sampai.

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

Ide ini dipinjam dari pertanyaan serupa: Bagaimana menjalankan fungsi JavaScript ketika saya memiliki namanya sebagai string

Komunitas
sumber
1
let players = [];
players[something] = {};
players[something].somethingElse = 'test';
console.log(players); 

-> [sesuatu: {somethingElse: 'test'}];

part1cle
sumber
0

Saat menggunakan jendela [objname], pastikan bahwa objname adalah variabel global. Jika tidak, akan berhasil kapan saja, dan terkadang gagal. window [objname] .value.

lyon819
sumber
0

Salah satu tantangan yang saya hadapi dengan jawabannya adalah mengasumsikan bahwa objek tersebut adalah satu level. Sebagai contoh,

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

bekerja dengan baik, tapi

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

tidak bekerja.

Apa yang akhirnya saya lakukan adalah membangun fungsi untuk mengakses objek multi-level:

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

Dalam skenario kedua, saya bisa meneruskan string ke fungsi ini untuk mendapatkan kembali objek yang saya cari:

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

Anda dapat menyetel properti objek dengan cara ini:

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

ThisisFish
sumber
0

Jika Anda sudah mengetahui daftar nama varible yang mungkin maka coba buat Objek baru (iconObj) yang nama propertinya sama dengan nama objek, Di sini, dalam contoh di bawah ini, variabel iconLib akan menampung dua nilai string, baik 'ZondIcons' atau 'MaterialIcons' . propertyName adalah properti dari ZondIcons atau objek MaterialsIcon.

   const iconObj = {
    ZondIcons,
    MaterialIcons,
  }
  const objValue = iconObj[iconLib][propertyName]
Sumeria
sumber
-1
var micro=[{'test':'hello'}];

var device = 'test';

console.log(micro[device]);
alfonsoolavarria.dll
sumber