Javascript değişkeni nesne adı olarak kullanır


91

Bir nesneye erişmek için bir değişkenin değerini kullanmak istiyorum.

Myobject adında bir nesnem olduğunu varsayalım.

Bir değişkeni bu isimle doldurmak ve değişkeni nesneye erişmek için kullanmak istiyorum.

Misal:

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

Yanıtlar:


125

Global:

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

console.log(this[anObjectName]);

Küresel: v2

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

console.log(myObject)

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

Yerel: v2

(function() {  
    var scope = this;

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

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

@Shaz - her ikisi de aslında aynı kapsama başvuruyor ;-) (Bir tarayıcıda çalıştırıldıklarını varsayarsak.) alert(this === window).
Sean Vieira

1
@PeeHaa - Yerel örnek üzerinde bir değişken setleri windowdenilen nesne objnamearacılığı sonra başvuruda bulunulan thissen yerine olabilir ... windowiçin thisikinci örnekteki ve her şey çalışma hala olur. :-)
Sean Vieira

1
@SeanVieira: Güncellenmiş örneğe bir göz atın. Umarım bu şimdi doğru çalışıyor.
Shaz

1
@Shaz - arguments.calleekullanımdan kaldırıldı, ancak yine de çok akıllıca bir uygulama - ve genel kapsamı daraltmıyor . +1
Sean Vieira

1
Küresel kapsamı kirletmiyor olabilir, ancak işlevin her çağrısı tarafından paylaşılan bir nesne yaratıyor. İşleviniz, objnameişlevin kendisinin bir özelliği olarak tutuyor . Özyinelemeli işlevler için başarısız olabilir. Bunun gerçek dünyada nasıl kullanılacağından emin değilim.
Juan Mendes

27

Değişken adının etrafında köşeli parantez kullanın.

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

7
Bu mükemmel ve basittir ve en iyi cevap olmalıdır.
Brad

5
Bu bir istisna atar: SyntaxError: beklenen ifade, var '.'. İşe yaramıyor; neden bu kadar çok olumlu oy?
Lovro

9

Global bir değişken mi? Eğer öyleyse, bunlar aslında windownesnenin parçalarıdır, yani yapabilirsiniz window[objname].value.

Bir işlev için yerelse, istediğinizi yapmanın iyi bir yolu olduğunu sanmıyorum.


8

Nesne bir kapsamda mevcuttur, bu nedenle bu sözdizimi aracılığıyla değişkene neredeyse her zaman erişebilirsiniz:

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

Bunun zorlaştığı tek yer, kapalı bir kapsamda olduğunuz ve üst düzey bir yerel değişkene erişmek istediğiniz zamandır. Böyle bir şeye sahip olduğunuzda:

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

Sen edebilirsiniz kullanarak etrafında olsun evalgeçerli kapsamı zincirini erişmek için yerine ... ama test bir sürü yaptık ve sürece bunu önermiyoruz biliyorum o şeyleri ele almak için en iyi yol olduğunu.

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

En iyi bahsiniz, her zaman orada olacak bir nesnede ( thisküresel kapsamda veya yerel kapsamdaki özel bir üst düzey değişken gibi ) bir isme referans vermek ve diğer her şeyi oraya koymaktır .

Böylece:

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

7

Şunları kullanabilirsiniz eval:

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

Değil mi evalkabul evil? Değilse kullanabilirim. Çünkü şu anda küresel bir durum ama onu bir şeyleri temizlemek için bir işleve taşımak istedim.
PeeHaa

1
Lol. Değişken adı kullanıcı girdisinden geliyorsa, evalyürütülebilecek herhangi bir JS kodu içermemesi için doğruladığınızdan emin olun .
Midas

1
evalBence bu, birkaç meşru kullanımdan biridir . Yine de değişkenin temiz olduğundan emin olmalıyız.
Levi Morrison

2
Evet gerçekten sorun değil. Ama Shaz'ın cevabına bir bakın. Bunun daha temiz bir çözüm olduğunu düşünüyorum.
Midas

2
@PeeHaa: Taşımayı düşünüyorsanız, neden onu bilinen bir nesnenin özelliğine taşımayasınız ki böyle bir şey yapabilirsiniz myVar[objname].value?
JW.

6

Bunu genel olarak, yazabileceğiniz pencere kapsamı dışında yapamazsınız. window[objname].value = 'value';


4

Özyinelemeli olmayan işlevler için işe yarasa da, Shaz'ın yerel değişkenler için cevabını anlamak zor. İşte daha net olduğunu düşündüğüm başka bir yol (ama yine de onun fikri, tamamen aynı davranış). Ayrıca yerel değişkenlere dinamik olarak erişmiyor, sadece yerel değişkenin özelliğine.

Esasen, global bir değişken kullanıyor (işlev nesnesine ekli)

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

Bu, değişkeni depolamak için bir global oluşturmakla temelde aynı şeydir, böylece ona bir özellik olarak erişebilirsiniz. Bunu yapmak için bir global yaratmak tam bir hile.

İşte global değişkenler oluşturmayan daha temiz bir hack, bunun yerine yerel bir değişken kullanıyor.

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

Bkz. Javascript: dizeyi nesne referansı olarak yorumlama?


1

Nesne bazı isim alanındaysa, yani. Company.Module.Components.Foobu işlevi kullanabilirsiniz:

CoffeeScript:

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

Sonuç 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;
}

Sonra yeni bir nesne oluşturabilir veya her şeyi yapabilirsiniz. Parantezleri not edin.

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

Bu fikir benzer sorudan ödünç alınmıştır: Adını bir dizge olarak aldığımda bir JavaScript işlevi nasıl çalıştırılır


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

-> [bir şey: {somethingElse: 'test'}];


0

[Objname] penceresini kullanırken, lütfen objname'nin global değişkenler olduğundan emin olun. Aksi takdirde bazen işe yarayacak ve bazen başarısız olacaktır. pencere [nesne adı] .value.


0

Cevaplarla karşılaştığım zorluklardan biri, nesnenin tek bir seviye olduğunu varsaymasıydı. Örneğin,

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

iyi çalışıyor, ama

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

çalışmıyor.

Sonunda yaptığım şey, çok seviyeli nesnelere erişmek için bir işlev oluşturmaktı:

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

İkinci senaryoda, aradığım nesneyi geri almak için dizeyi bu işleve geçirebilirim:

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

0

Bir nesne özelliğini şu şekilde ayarlayabilirsiniz:

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


0

Olası değişken adların listesini zaten biliyorsanız, özellikleri adı nesne adlarıyla aynı olan yeni bir Nesne (iconObj) oluşturmayı deneyin. Aşağıdaki örnekte, iconLib değişkeni 'ZondIcons' veya 'MaterialIcons' olmak üzere iki dize değeri tutacaktır. . propertyName, ZondIcons veya MaterialsIcon nesnesinin özelliğidir.

   const iconObj = {
    ZondIcons,
    MaterialIcons,
  }
  const objValue = iconObj[iconLib][propertyName]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.