जावास्क्रिप्ट का उपयोग चर नाम वस्तु के रूप में किया जाता है


91

मैं एक वस्तु तक पहुंचने के लिए एक चर के मूल्य का उपयोग करना चाहता हूं।

मान लीजिए कि मेरे पास myobject नाम की एक वस्तु है।

मैं इस नाम के साथ एक चर भरना चाहता हूं और ऑब्जेक्ट तक पहुंचने के लिए चर का उपयोग करता हूं।

उदाहरण:

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

जवाबों:


125

ग्लोबल:

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

console.log(this[anObjectName]);

ग्लोबल: v2

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

console.log(myObject)

स्थानीय: 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);
})();

स्थानीय: v2

(function() {  
    var scope = this;

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

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

@ शाज - उन दोनों वास्तव में एक ही गुंजाइश है;; (यह मानते हुए कि वे एक ब्राउज़र में निष्पादित हैं।) alert(this === window)।
— सीन विएरा

1
@PeeHaa - स्थानीय उदाहरण windowऑब्जेक्ट पर एक चर सेट करता है जिसे objnameतब संदर्भित किया जाता है जिसके माध्यम से this... आप दूसरे उदाहरण के windowलिए स्थानापन्न कर सकते हैं thisऔर सब कुछ अभी भी काम करेगा। :-)
— शॉन विएरा

1
@ सीनवीरा: अद्यतन उदाहरण पर एक नज़र डालें। उम्मीद है कि यह अब सही ढंग से काम करता है।
— Shaz

1
@ शाज - arguments.calleeपदावनत है, लेकिन फिर भी यह एक बहुत ही चतुर कार्यान्वयन है - और यह वैश्विक दायरे में नहीं है। +1
— सीन विएरा

1
यह वैश्विक दायरे को प्रदूषित नहीं कर सकता है, लेकिन यह एक ऐसी वस्तु का निर्माण कर रहा है जो फ़ंक्शन के हर आह्वान द्वारा साझा की जाती है। आपका फ़ंक्शन objnameस्वयं फ़ंक्शन की एक संपत्ति के रूप में पकड़ रहा है। यह पुनरावर्ती कार्यों के लिए विफल हो सकता है। यह निश्चित नहीं है कि वास्तविक दुनिया में इसका उपयोग कैसे किया जा सकता है।
— जुआन मेंडेस

27

चर नाम के चारों ओर वर्ग ब्रैकेट का उपयोग करें।

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

7
यह सही और सरल है और शीर्ष उत्तर होना चाहिए।
— ब्रैड

5
यह एक अपवाद फेंकता है: SyntaxError: अपेक्षित अभिव्यक्ति, मिला '।'। यह काम नहीं करता; इतने अपवित्र क्यों?
— लोवरो

9

यह एक वैश्विक चर है? यदि हां, तो ये वास्तव में windowवस्तु का हिस्सा हैं , इसलिए आप कर सकते हैं window[objname].value।

यदि यह एक समारोह के लिए स्थानीय है, तो मुझे नहीं लगता कि वहाँ एक अच्छा तरीका है कि आप क्या चाहते हैं।


8

ऑब्जेक्ट कुछ दायरे में मौजूद है, इसलिए आप इस सिंटैक्स के माध्यम से लगभग हमेशा चर तक पहुंच सकते हैं:

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

एकमात्र स्थान जहां यह मुश्किल हो जाता है जब आप एक बंद दायरे में होते हैं और आप एक शीर्ष-स्तरीय स्थानीय चर तक पहुंच चाहते हैं। जब आपके पास ऐसा कुछ हो:

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

आप कर सकते हैं कि evalवर्तमान गुंजाइश श्रृंखला का उपयोग करने के बजाय का उपयोग करके ... लेकिन जब तक आप बहुत सारे परीक्षण नहीं कर लेते और मैं नहीं जानता कि यह चीजों के बारे में जाने का सबसे अच्छा तरीका है।

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

आपकी सबसे अच्छी शर्त यह है कि हमेशा-जाने-आने वाली वस्तु में एक नाम का संदर्भ दिया जाए (जैसे thisवैश्विक स्कोप में या स्थानीय स्कोप में एक निजी टॉप-लेवल वैरिएबल) और बाकी सब कुछ उसमें डाल दें ।

इस प्रकार:

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

आप उपयोग कर सकते हैं eval:

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

नहीं evalमाना जाता है evil? अगर नहीं तो मैं इसका इस्तेमाल कर सकता हूं। क्योंकि यह अभी वैश्विक है लेकिन मैं इसे सामान को साफ करने के लिए एक समारोह में ले जाना चाहता था।
— PeeHaa

1
जबरदस्त हंसी। यदि वैरिएबल नाम उपयोगकर्ता इनपुट से आता है, तो सुनिश्चित करें कि आप इसे मान्य करते हैं, ताकि इसमें कोई जेएस कोड न हो जो evalनिष्पादित कर सके।
— मिडास

1
यह evalमेरी राय में, के कुछ वैध उपयोगों में से एक है । हमें यह सुनिश्चित करना होगा कि चर साफ है, हालांकि।
— लेवी मॉरिसन

2
हाँ यह वास्तव में कोई समस्या नहीं है। लेकिन शाज़ के जवाब पर एक नज़र डालें। मुझे लगता है कि यह एक अधिक स्वच्छ समाधान है।
— मिडास

2
@PeeHaa: यदि आप इसे स्थानांतरित करने पर विचार कर रहे हैं, तो इसे किसी ज्ञात वस्तु की संपत्ति में स्थानांतरित क्यों नहीं किया जाए, तो आप कुछ ऐसा कर सकते हैं myVar[objname].value?
— जेडब्ल्यू।

6

आप इसे सामान्य रूप से नहीं कर सकते, सिवाय खिड़की के दायरे में, जहां आप लिख सकते हैं window[objname].value = 'value';


4

मुझे लगता है कि स्थानीय चर के लिए शाज़ का जवाब समझना कठिन है, हालांकि यह गैर-पुनरावर्ती कार्यों के लिए काम करता है। यहां एक और तरीका है जो मुझे लगता है कि यह स्पष्ट है (लेकिन यह अभी भी उसका विचार है, सटीक एक ही व्यवहार)। यह गतिशील रूप से स्थानीय चर का उपयोग नहीं कर रहा है, बस स्थानीय चर की संपत्ति है।

अनिवार्य रूप से, यह एक वैश्विक चर (फ़ंक्शन ऑब्जेक्ट से जुड़ी) का उपयोग कर रहा है

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

यह मूल रूप से वैरिएबल को स्टोर करने के लिए एक वैश्विक बनाने जैसी ही चीज है, इसलिए आप इसे एक संपत्ति के रूप में एक्सेस कर सकते हैं। ऐसा करने के लिए एक वैश्विक बनाना एक ऐसी हैक है।

यहां एक क्लीनर हैक है जो वैश्विक चर नहीं बनाता है, यह इसके बजाय एक स्थानीय चर का उपयोग करता है।

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

जावास्क्रिप्ट देखें : ऑब्जेक्ट संदर्भ के रूप में व्याख्या स्ट्रिंग?


1

यदि वस्तु कुछ नामस्थान में है। Company.Module.Components.Fooआप इस फ़ंक्शन का उपयोग कर सकते हैं:

CoffeeScript:

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

परिणामी 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;
}

फिर आप एक नई वस्तु बना सकते हैं या जो कुछ भी कर सकते हैं। के माध्यम से parenthises पर ध्यान दें।

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

इस विचार को इसी तरह के प्रश्न से उधार लिया गया है: जब मेरा नाम एक स्ट्रिंग के रूप में है, तो जावास्क्रिप्ट फ़ंक्शन को कैसे निष्पादित किया जाए


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

-> [कुछ: {somethingElse: 'test'}];


0

खिड़की का उपयोग करते समय [objname], कृपया सुनिश्चित करें कि objname वैश्विक चर है। अन्यथा, कभी-कभी काम करेगा, और कभी-कभी असफल हो जाएगा। विंडो [objname] .Value।


0

उत्तरों के साथ मेरे पास जो चुनौतियाँ थीं, उनमें से एक यह है कि यह मान लिया गया था कि वस्तु एकल स्तर है। उदाहरण के लिए,

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

ठीक काम करता है, लेकिन

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

काम नहीं करता।

मैंने जो किया, वह बहु-स्तरीय वस्तुओं तक पहुँचने के लिए एक समारोह का निर्माण कर रहा था:

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

दूसरे परिदृश्य में, मैं इस फ़ंक्शन को वापस उसी वस्तु को प्राप्त करने के लिए पास कर सकता हूं जिसे मैं देख रहा हूं:

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


0

यदि आप पहले से ही संभव परिवर्तनीय नामों की सूची जानते हैं, तो एक नया ऑब्जेक्ट (iconObj) बनाने का प्रयास करें, जिसका गुण नाम ऑब्जेक्ट नाम के समान है, यहाँ नीचे दिए गए उदाहरण में, iconLib वेरिएबल दो स्ट्रिंग मान रखेगा, या तो 'ZondIcons' या 'MaterialIcons' । propertyName ZondIcons या MaterialIcon ऑब्जेक्ट की संपत्ति है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.