वैरिएबल का उपयोग करके ऑब्जेक्ट प्रॉपर्टी को गतिशील रूप से एक्सेस करें


721

मैं गतिशील नाम का उपयोग करके किसी ऑब्जेक्ट की संपत्ति तक पहुंचने का प्रयास कर रहा हूं। क्या यह संभव है?

const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"

जवाबों:


958

किसी वस्तु के गुणों तक पहुंचने के दो तरीके हैं :

  • डॉट नोटेशन: something.bar
  • ब्रैकेट संकेतन: something['bar']

कोष्ठक के बीच का मान किसी भी अभिव्यक्ति हो सकता है। इसलिए, यदि प्रॉपर्टी का नाम एक चर में संग्रहीत है, तो आपको ब्रैकेट नोटेशन का उपयोग करना होगा:

var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected

34
इस के साथ सावधान: जावास्क्रिप्ट संकलक यहाँ त्रुटि करेगा क्योंकि वे तार का नाम नहीं बदलते हैं, लेकिन वे ऑब्जेक्ट गुण का नाम बदलते हैं
chacham15

6
यह क्यों संभव है पर कुछ और जानकारी: जेएस ऑब्जेक्ट्स एसोसिएटिव एरेज़ हैं, इसीलिए। आगे पढ़ना: quirksmode.org/js/associative.html stackoverflow.com/questions/14031368/…
सुधांशु मिश्रा

@dotnetguy नहीं वे नहीं हैं। Arrays ऐसी वस्तुएं हैं जो सादे JS ऑब्जेक्ट प्रोटोटाइप से विरासत में मिली हैं और इसलिए आप किसी भी सादे ऑब्जेक्ट की तरह गो-गो को जोड़ सकते हैं। The साहचर्य ’व्यवहार सरणी की तरह अधिक वस्तु-जैसा है। आप साधारण सूचकांक द्वारा 'साहचर्य' संस्करण को पुनरावृत्त नहीं कर सकते, इसलिए यह सरणी-जैसा व्यवहार प्रदर्शित नहीं कर रहा है। आप अपने 'साहचर्य' के ऐरे को {} या [] के रूप में परिभाषित कर सकते हैं और जहां तक ​​यादृच्छिक संपत्ति की पहुंच का संबंध है, दोनों में ही इसका व्यवहार करते हैं।
वंचित वोमैट

3
@VanquishedWombat सुनिश्चित नहीं है कि आपकी आपत्ति किससे संबंधित है? मैंने यह नहीं कहा कि जेएस ऑब्जेक्ट एरेज़ हैं?
सुधांशु मिश्रा

1
यह उत्तर अधिक मतदान का है, यह कुछ भी स्पष्ट नहीं करता है ...
Aft3rL1f3

104

यह मेरा समाधान है:

function resolve(path, obj) {
    return path.split('.').reduce(function(prev, curr) {
        return prev ? prev[curr] : null
    }, obj || self)
}

उपयोग के उदाहरण:

resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject) 
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})

उत्कृष्ट उत्तर, यह भी देखें: stackoverflow.com/questions/37510640/…
जूलियन नाइट

2
आपने मुझे एक उन्नत संस्करण बनाने के लिए प्रेरित किया, जो इनपुट के सत्यापन के साथ-साथ रिक्त स्थान के साथ ब्रैकेट संकेतन और संपत्ति के नाम की अनुमति देता है: it.knightnet.org.uk/kb/node-js/get-properties
जूलियन नाइट

मुझे यह समाधान पसंद है। हालाँकि मैं मूल ऑब्जेक्ट में मानों को संशोधित करने की कोशिश कर रहा हूं, ऐसा लगता है कि आपका फ़ंक्शन ऑब्जेक्ट की एक उप प्रति लौटाता है। क्या इसे बदलना संभव है ताकि लौटी हुई वस्तु को संशोधित करके मूल को संशोधित किया जा सके?
ईगल 1

40

जावास्क्रिप्ट में हम साथ पहुँच सकते हैं:

  • डॉट नोटेशन - foo.bar
  • वर्ग कोष्ठक - foo[someVar]याfoo["string"]

लेकिन केवल दूसरा मामला गतिशील रूप से संपत्तियों तक पहुंचने की अनुमति देता है:

var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}

var name = "pName"
var num  = 1;

foo[name + num]; // 1

// -- 

var a = 2;
var b = 1;
var c = "foo";

foo[name + a][b][c]; // bar

4
अगर बयानों की 2,000 पंक्तियों को मैं देख रहा हूं क्योंकि पिछले देव ने वर्ग कोष्ठक का उपयोग नहीं किया था, और डॉट संकेतन द्वारा सांख्यिकीय रूप से एक्सेस की गई वस्तु गुण। यह एक अनुमोदन प्रक्रिया ऐप के लिए है जिसमें 7 अलग-अलग अनुमोदन हैं और चरण सभी समान हैं। / रिप
चाड

26

निम्नलिखित एक ES6 उदाहरण है कि आप एक संपत्ति के नाम का उपयोग कैसे कर सकते हैं जो एक संपत्ति नाम का उपयोग करता है जो गतिशील रूप से दो तारों को जोड़कर उत्पन्न किया गया है।

var suffix = " name";

var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};

console.log(person["first name"]);      // "Nicholas"
console.log(person["last name"]);       // "Zakas"

इसे कंप्यूटेड प्रॉपर्टी नेम कहा जाता है


16

आप इसे कुछ अलग तरीकों से हासिल कर सकते हैं।

let foo = {
    bar: 'Hello World'
};

foo.bar;
foo['bar'];

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

let foo = {
    bar: 'Hello World'
};

let prop = 'bar';

foo[prop];

यह एक वस्तु के हर संपत्ति पर पाशन के लिए बढ़ाया जा सकता है। यह नए जावास्क्रिप्ट के कारण बेमानी लग सकता है जैसे कि ... के लिए ..., लेकिन एक उपयोग के मामले को समझाने में मदद करता है:

let foo = {
    bar: 'Hello World',
    baz: 'How are you doing?',
    last: 'Quite alright'
};

for (let prop in foo.getOwnPropertyNames()) {
    console.log(foo[prop]);
}

डॉट और ब्रैकेट नोटेशन दोनों नेस्टेड ऑब्जेक्ट्स के लिए अपेक्षित के रूप में भी काम करते हैं:

let foo = {
    bar: {
        baz: 'Hello World'
    }
};

foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;

वस्तु नष्ट होना

हम किसी वस्तु में किसी संपत्ति तक पहुंचने के साधन के रूप में विनाशकारी वस्तु पर भी विचार कर सकते हैं, लेकिन निम्नानुसार है:

let foo = {
    bar: 'Hello World',
    baz: 'How are you doing?',
    last: 'Quite alright'
};

let prop = 'last';
let { bar, baz, [prop]: customName } = foo;

// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'

11

आप इसे इस तरह से कर सकते हैं जैसे कि Lodash get का उपयोग करना

_.get(object, 'a[0].b.c');

कई स्थितियां हैं, जैसे कि गहरी नेस्टेड ऑब्जेक्ट लुकअप, जहां यह एकमात्र विकल्प है।
जोनाथन केम्फ

8

UPDATED

मैंने नीचे टिप्पणी पर विचार किया और सहमति व्यक्त की। ईवैल से बचना है।

ऑब्जेक्ट में रूट प्रॉपर्टीज को एक्सेस करना आसानी से हासिल हो जाता है obj[variable], लेकिन नेस्टेड हो जाने से बात उलझ जाती है। पहले से लिखे गए कोड को लिखने के लिए नहीं जिसका मैं उपयोग करने का सुझाव देता हूं lodash.get

उदाहरण

// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);

// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);

लॉडश गेट का उपयोग विभिन्न तरीकों से किया जा सकता है, यहां दस्तावेज़ीकरण दर्ज करें


4
evalजब भी संभव हो इसका उपयोग करने से बचना सबसे अच्छा है। stackoverflow.com/questions/86513/…
ल्यूक

8
evalगुणों तक पहुँचने के रूप में तुच्छ के लिए कुछ का उपयोग करना सादे ओवरकिल है और किसी भी परिस्थिति में मुश्किल से उचित है। "परेशानी" क्या है? obj['nested']['test']बहुत अच्छी तरह से काम करता है और तार में एम्बेड कोड करने की आवश्यकता नहीं है।
Kyll

3
eval तीन गुना धीमा या अधिक है, मैं इसे newbies को नहीं सुझाऊंगा क्योंकि यह उन्हें बुरी आदतें सिखा सकता है। मैं उपयोग करता हूं obj['nested']['value']- बच्चों को याद करो, बुराई बुराई है!
jaggedsoft

1
@ लुक वह अब केवल लोध _.getको मेज पर लाना चाहता है । मुझे लगता है कि यह जवाब नीचे के बजाय अब बढ़ रहा है। यह ओवरकिल हो सकता है, लेकिन यह जानना अच्छा है कि यह मौजूद है।
एमिल बर्जरॉन

1
इसके लिए लॉश शुरू करने के लिए धन्यवाद। मैं एक वस्तु में गहराई से मूल्य निर्धारित करने के लिए एक विधि की तलाश में गूगल द्वारा यहां आया था, और उनकी _.set विधि (जो कि ऊपर के समान है, लेकिन सेट करने के लिए मूल्य के लिए अतिरिक्त तर्क के साथ) का उपयोग किया है।
TPHughes

5

जब भी आपको संपत्ति को गतिशील रूप से एक्सेस करने की आवश्यकता होती है, तो आपको संपत्ति तक पहुंचने के लिए स्क्वायर ब्रैकेट का उपयोग करना होगा ""। ऑपरेटर
सिंटैक्स: ऑब्जेक्ट [उचित]

const something = { bar: "Foobar!" };
const foo = 'bar';
// something.foo; -- not correct way at it is expecting foo as proprty in  something={ foo: "value"};
// correct way is  something[foo]
alert( something[foo])


4

मैं एक ऐसे मामले में आया था, जहां मुझे लगा कि मैं किसी अन्य फ़ंक्शन के डेटा के रूप में किसी ऑब्जेक्ट प्रॉपर्टी का "पता" पास करना चाहता हूं और ऑब्जेक्ट को पॉप (AJAX के साथ) करता हूं, एड्रेस एरे से लुकअप करता हूं, और उस अन्य फ़ंक्शन में प्रदर्शित करता हूं। मैं स्ट्रिंग कलाबाजी किए बिना डॉट नोटेशन का उपयोग नहीं कर सकता था, इसलिए मुझे लगा कि इसके बजाय एक सरणी पास करना अच्छा हो सकता है। मैंने वैसे भी कुछ अलग किया, लेकिन इस पोस्ट से संबंधित था।

यहां एक भाषा फ़ाइल ऑब्जेक्ट का एक नमूना है जैसे कि मैं उससे डेटा चाहता था:

const locs = {
  "audioPlayer": {
    "controls": {
      "start": "start",
      "stop": "stop"
    },
    "heading": "Use controls to start and stop audio."
  }
}

मैं इस तरह के रूप में एक सरणी पारित करने में सक्षम होना चाहता था: ["ऑडियोप्लेयर", "नियंत्रण", "रोक"] इस मामले में भाषा पाठ का उपयोग करने के लिए, "रोकें"।

मैंने यह छोटा फ़ंक्शन बनाया जो "कम से कम विशिष्ट" (पहला) पता पैरामीटर दिखता है, और लौटी हुई वस्तु को अपने आप में पुन: असाइन करता है। फिर यह अगले-विशिष्ट-विशिष्ट पते पैरामीटर को देखने के लिए तैयार है यदि कोई मौजूद है।

function getText(selectionArray, obj) {
  selectionArray.forEach(key => {
    obj = obj[key];
  });
  return obj;
}

उपयोग:

/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs)); 

/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs)); 

2

यह दिलचस्प हो जाता है जब आपको इस फ़ंक्शन के मापदंडों को भी पास करना पड़ता है।

कोड jsfiddle

var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}

var str = "method('p1', 'p2', 'p3');"

var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);

var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
  // clean up param begninning
    parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
  // clean up param end
  parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}

obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values

1

ES5 // डीप नेस्टेड वेरिएबल्स की जांच करें

कोड का यह सरल टुकड़ा जिस तरह से साथ प्रत्येक चर की जांच करने के लिए गहरी नेस्टेड चर / मूल्य अस्तित्व के लिए जाँच कर सकते हैं ...

var getValue = function( s, context ){
    return Function.call( context || null, 'return ' + s )();
}

पूर्व। - वस्तुओं की एक गहरी नेस्टेड सरणी:

a = [ 
    {
      b : [
          {
             a : 1,
             b : [
                 {
                    c : 1,
                    d : 2   // we want to check for this
                 }
             ]
           }
      ]
    } 
]

के बजाय :

if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 )  // true

अब हम कर सकते हैं:

if( getValue('a[0].b[0].b[0].d') == 2 ) // true

चीयर्स!


1
यदि समाधान को निष्कासन का उपयोग करना है, तो आपने सिर्फ एक लाख अन्य समस्याएं पैदा की हैं।
रोड्रिगो लेइट

@ रोड्रोडोलाइट ठीक है, इसलिए कम से कम एक देने की समस्या नहीं होगी ...


1
@RodrigoLeite मैंने इसे पढ़ा है, और Functionइसके बजाय उपयोग करने के लिए समाधान अपडेट किया है

0

मैंने एक सवाल पूछा कि थोड़े समय पहले थोड़े समय बाद इस विषय पर डुप्लिकेट किया गया था, और अत्यधिक शोध के बाद, और बहुत सारी जानकारी गायब है जो यहां होनी चाहिए, मुझे लगता है कि मुझे इस पुराने पोस्ट में जोड़ने के लिए कुछ मूल्यवान है।

  • सबसे पहले मैं यह जानना चाहता हूं कि संपत्ति के मूल्य को प्राप्त करने और एक गतिशील चर में संग्रहीत करने के कई तरीके हैं। पहला सबसे लोकप्रिय और सबसे आसान तरीका IMHO होगा:
let properyValue = element.style['enter-a-property'];

हालाँकि, मैं शायद ही कभी इस मार्ग पर जाता हूँ क्योंकि यह शैली-पत्रक के माध्यम से निर्दिष्ट संपत्ति मूल्यों पर काम नहीं करता है। आपको एक उदाहरण देने के लिए, मैं कुछ छद्म कोड के साथ प्रदर्शित करूँगा।

 let elem = document.getElementById('someDiv');
 let cssProp = elem.style['width'];

ऊपर दिए गए कोड उदाहरण का उपयोग करना; यदि div तत्व की चौड़ाई गुण जो 'elem' वैरिएबल में संग्रहीत किया गया था, एक CSS स्टाइल-शीट में स्टाइल किया गया था, और इसके HTML टैग के अंदर स्टाइल नहीं किया गया था, तो आप एक शक के बिना अपरिभाषित के एक रिटर्न वैल्यू को प्राप्त करने जा रहे हैं। cssProp चर के। अपरिभाषित मूल्य इसलिए होता है क्योंकि सही मान प्राप्त करने के लिए, सीएसएस स्टाइल-शीट के अंदर लिखे कोड को मूल्य प्राप्त करने के लिए गणना करने के लिए गणना करने की आवश्यकता होती है; आपको एक ऐसी विधि का उपयोग करना चाहिए जो उस संपत्ति के मूल्य की गणना करेगा जो मूल्य शैली-पत्रक के भीतर है।

  • इसके बाद getComputedStyle () विधि प्राप्त करें!
function getCssProp(){
  let ele = document.getElementById("test");
  let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}

W3Schools getComputedValue Doc यह एक अच्छा उदाहरण देता है, और आपको इसके साथ खेलने की सुविधा देता है, हालाँकि, यह लिंक Mozilla CSS getComputedValue doc getComputedValue फ़ंक्शन के बारे में विस्तार से बताता है, और इसे किसी भी इच्छुक डेवलपर द्वारा पढ़ा जाना चाहिए जो इस विषय पर पूरी तरह से स्पष्ट नहीं है।

  • एक साइड नोट के रूप में, getComputedValue विधि केवल मिलती है, यह सेट नहीं होती है। यह स्पष्ट रूप से एक प्रमुख नकारात्मक पहलू है, हालांकि सीएसएस शैली-शीट्स से एक विधि है, साथ ही साथ मान सेट करता है, हालांकि यह मानक जावास्क्रिप्ट नहीं है। JQuery विधि ...
$(selector).css(property,value)

... मिलता है, और सेट होता है। यह वही है जो मैं उपयोग करता हूं, केवल नकारात्मक पक्ष आपको JQuery के बारे में पता चलता है, लेकिन यह ईमानदारी से बहुत अच्छे कारणों में से एक है कि प्रत्येक जावास्क्रिप्ट डेवलपर को JQuery सीखना चाहिए, यह सिर्फ जीवन को आसान बनाता है, और इस तरह की विधियों की पेशकश करता है, जो मानक जावास्क्रिप्ट के साथ उपलब्ध नहीं है। आशा है कि यह किसी की मदद करता है !!!


0

नेस्टेड वैरिएबल की वैल्यू सेट करने की चाहत रखने वाले किसी व्यक्ति के लिए, यह कैसे करना है:

const _ = require('lodash'); //import lodash module

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4

प्रलेखन: https://lodash.com/docs/4.17.15#set

यदि आप कोई मूल्य प्राप्त करना चाहते हैं, तो भी प्रलेखन: https://lodash.com/docs/4.17.15#get



-4
const something = { bar: "Foobar!" };
const foo = 'bar';

something[\`${foo}\`];

7
पृथ्वी पर आप ऐसा क्यों करेंगे? आपका fooपहले से ही एक स्ट्रिंग है, इसलिए `${foo}`के रूप में बिल्कुल वैसा ही है foo। (इसके अलावा, आपके कोड में कुछ अतिरिक्त बैकस्लैश हैं, जो वहां नहीं हैं। लेकिन यह तब भी व्यर्थ होगा, जब आप उस वाक्यविन्यास त्रुटि को ठीक कर
लेंगे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.