वस्तु शाब्दिक / आरम्भिकों में स्व-संदर्भ


706

क्या जावास्क्रिप्ट में काम करने के लिए कुछ पाने का कोई तरीका है?

var foo = {
    a: 5,
    b: 6,
    c: this.a + this.b  // Doesn't work
};

वर्तमान रूप में, यह कोड स्पष्ट रूप से एक संदर्भ त्रुटि फेंकता है क्योंकि thisयह संदर्भित नहीं करता है foo। लेकिन है वहाँ एक वस्तु शाब्दिक के गुणों में मूल्यों के लिए किसी भी तरह से अन्य गुणों पर निर्भर पहले घोषित?

जवाबों:


744

ठीक है, केवल एक चीज मैं आपको बता सकता है कि के बारे में हैं गेटर :

var foo = {
  a: 5,
  b: 6,
  get c() {
    return this.a + this.b;
  }
}

console.log(foo.c) // 11

यह ECMAScript 5 वें संस्करण की विशिष्टता द्वारा पेश किया गया एक सिंटैक्टिक एक्सटेंशन है, सिंटैक्स अधिकांश आधुनिक ब्राउज़रों (IE9 सहित) द्वारा समर्थित है।


32
बहुत ही उपयोगी उत्तर। 'प्राप्त' के बारे में अधिक जानकारी यहाँ पाई जा सकती है: developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/…
jake

5
@FaustoR। हाँ यह करता है।
चार्ली मार्टिन

48
इस समाधान से सावधान रहें कि यदि मानों को बदल दिया जाता है foo.aया foo.bफिर बदल जाएगा, तो मूल्य foo.cभी तुल्यकालन में बदल जाएगा। यह आवश्यक हो सकता है या नहीं हो सकता है।
HBP

8
ध्यान दें कि thisसबसे गहरी नेस्टेड ऑब्जेक्ट को बांधता है। जैसे:... x: { get c () { /*this is x, not foo*/ } } ...
Z. खुल्ला

3
मेरे उपरोक्त कथन को पूरा करने के लिए, चूंकि fooमधुमक्खी को एक चर के रूप में घोषित किया जाता है और cइसका मूल्यांकन केवल उस समय किया जाता है जब इसे लागू किया जाता है, fooअंदर का उपयोग cकाम करेगा, विरोध के रूप में this(हालांकि सावधान रहें)
Z. खुल्लाह

316

आप कुछ ऐसा कर सकते हैं:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();

यह किसी प्रकार की वस्तु के आरम्भिक समय के लिए होगा।

नोट आप वास्तव में की वापसी मान निर्दिष्ट कर रहे हैं कि init()करने के लिए fooहै, इसलिए आप के लिए है return this


95
आप delete this.initपहले भी return thisऐसा कर सकते हैं जो कि fooपॉलेटेड नहीं है
बिली मून

15
@ बिलीमून: हां वास्तव में, हालांकि ऐसा करने से उस वस्तु पर सभी बाद की संपत्ति का प्रदर्शन प्रभावित होता है, कई इंजनों पर (V8, उदाहरण के लिए)।
टीजे क्राउडर

8
@ मुहम्मदउमर: यह सुनिश्चित नहीं करते हैं कि ईएस 6 कक्षाएं कैसे प्रासंगिक हैं।
फेलिक्स क्लिंग

8
@ मुहम्मदउमर: निर्माण कार्यों के लिए कक्षाएं सिंटैक्टिक शुगर हैं, इसलिए वे वास्तव में कुछ नया प्रदान नहीं करते हैं। किसी भी तरह से, इस सवाल का मुख्य ध्यान वस्तु शाब्दिक हैं।
फेलिक्स क्लिंग

3
@akantoword: ग्रेट :) चूंकि ऑब्जेक्ट शाब्दिक एक एकल अभिव्यक्ति हैं, इसलिए init()कॉल को सीधे एकल अभिव्यक्ति रखने के लिए शाब्दिक रूप से जोड़ा गया था। लेकिन निश्चित रूप से आप फ़ंक्शन को अलग से कॉल कर सकते हैं जिसे आप चाहते हैं।
फेलिक्स क्लिंग

181

स्पष्ट, सरल उत्तर गायब है, इसलिए पूर्णता के लिए:

लेकिन है वहाँ एक वस्तु शाब्दिक के गुणों में मूल्यों के लिए किसी भी तरह से अन्य गुणों पर निर्भर पहले घोषित?

नहीं। यहां पर सभी समाधान तब तक टाल दिए जाते हैं जब तक कि वस्तु का निर्माण (विभिन्न तरीकों से) नहीं हो जाता है और फिर तीसरी संपत्ति सौंपते हैं। इसका सबसे सरल तरीका यह है:

var foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;

अन्य सभी एक ही काम करने के लिए अधिक अप्रत्यक्ष तरीके हैं। (फेलिक्स विशेष रूप से चतुर है, लेकिन एक अस्थायी फ़ंक्शन को बनाने और नष्ट करने की आवश्यकता है, जटिलता को जोड़ना और या तो वस्तु पर एक अतिरिक्त संपत्ति छोड़ देता है या [यदि आप deleteवह संपत्ति] उस वस्तु पर बाद की संपत्ति पहुंच के प्रदर्शन को प्रभावित करते हैं।)

यदि आपको इसकी आवश्यकता है कि सभी एक अभिव्यक्ति के भीतर हों, तो आप यह कर सकते हैं कि अस्थायी संपत्ति के बिना:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});

या बेशक, अगर आपको एक से अधिक बार ऐसा करने की आवश्यकता है:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}

फिर आपको इसका उपयोग करने की आवश्यकता कहां है:

var foo = buildFoo(5, 6);

अपनी खुद की पवित्रता के लिए, मैं आधिकारिक दस्तावेज के कुछ प्रकार खोजने की कोशिश कर रहा हूं जो मूल रूप से एक ही बात कहते हैं - कि एक वस्तु thisकेवल उक्त वस्तु के तरीकों के लिए उपलब्ध है , और किसी अन्य प्रकार के गुण नहीं। कोई भी विचार जहां मुझे मिल सकता है? धन्यवाद!
डेविड केनेल

1
@DavidKennell: विनिर्देश से अधिक आधिकारिक नहीं है । :-) आप शायद यहाँ शुरू करेंगे और इसके माध्यम से अनुसरण करेंगे। यह काफी अजीब भाषा है, लेकिन मूल रूप से आप संपत्ति परिभाषा मूल्यांकन के विभिन्न उपवर्गों में देखेंगे कि ऑब्जेक्ट संपत्ति इनिशियलाइज़र के मूल्यों को निर्धारित करने वाले संचालन के लिए उपलब्ध नहीं है।
टीजे क्राउडर

मैं यहाँ ब्राउज़र्सस्कोप के परिणाम नहीं देख सकता , लेकिन यह अधिक सही मामला नहीं है? मेरे वातावरण में, v8: delete10% तेज है और जियोको: deleteसिर्फ 1% धीमा है।
TheMaster

1
@ TheMaster - हाँ, मुझे नहीं लगता कि BrowserScope वास्तव में अब कोई चीज़ है। ऐसा लगता है कि हटाना उतना बुरा नहीं है जितना पहले हुआ करता था, कम से कम वी 8 (क्रोम, आदि) या स्पाइडरमोंकी में नहीं। अभी भी धीमी है, लेकिन केवल एक छोटा सा है, और ये चीजें इन दिनों तेजी से अजीब हैं।
टीजे क्राउडर

63

बस एक अनाम फ़ंक्शन को तत्काल:

var foo = new function () {
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
};

1
@ बरगी, क्यों? क्योंकि हो सकता है कि कोई व्यक्ति उसी वस्तु से किसी अन्य वस्तु को पलटे? ऐसा नहीं है कि वे सिर्फ एक वस्तु शाब्दिक क्लोन नहीं कर सकते। यह एक तर्क new Point(x, y)को पारित करने से अलग नहीं है, सिवाय इसके कि फ़ंक्शन का पुन: उपयोग के लिए नाम नहीं दिया गया है।
zzzzBov 16

1
@zzzzBov: बेशक वे सिर्फ ऑब्जेक्ट को क्लोन कर सकते हैं, लेकिन IEFE समाधान की तुलना में (जैसे TJCrowder के जवाब में) आपका समाधान कंस्ट्रक्टर फ़ंक्शन को लीक करता है और एक शानदार प्रोटोटाइप ऑब्जेक्ट बनाता है।
बर्गी

5
@zzzzBov: बस वह प्रयोग करें var foo = function() { this.…; return this; }.call({});जो वाक्य-रचना में बहुत भिन्न न होकर शब्दार्थ से हो।
बेर्गी

1
@ बर्गी, अगर आपको लगता है कि यह महत्वपूर्ण है, तो मिक्स में अपना जवाब क्यों न जोड़ें?
zzzzBov

3
आपको यह मिल गया है। मैंने वास्तव में newकीवर्ड नहीं देखा था ।
रैंडी

26

अब ES6 में आप आलसी कैश्ड गुण बना सकते हैं। पहली बार उपयोग करने पर संपत्ति सामान्य स्थिर संपत्ति बनने के लिए एक बार मूल्यांकन करती है। परिणाम: दूसरी बार गणित समारोह ओवरहेड छोड़ दिया जाता है।

जादू करने वाले में है।

const foo = {
    a: 5,
    b: 6,
    get c() {
        delete this.c;
        return this.c = this.a + this.b
    }
};

तीर पाने वाले thisमें आस-पास के शाब्दिक दायरे को चुनता है

foo     // {a: 5, b: 6}
foo.c   // 11
foo     // {a: 5, b: 6 , c: 11}  

1
es5 में वे गुण भी होते हैं जिन्हें आपको Object.defineProperty(foo, 'c', {get:function() {...}})उन्हें परिभाषित करने के लिए उपयोग करने की आवश्यकता होती है। यह इस तरह के एक कारखाने में आसानी से विनीत तरीके से किया जाता है। बेशक यदि आप getचीनी का उपयोग कर सकते हैं तो यह अधिक पठनीय है लेकिन क्षमता वहाँ है।
अलुआन हद्दाद

21

कुछ बंद को इससे निपटना चाहिए;

var foo = function() {
    var a = 5;
    var b = 6;
    var c = a + b;

    return {
        a: a,
        b: b,
        c: c
    }
}();

आपके द्वारा घोषित सभी चर fooनिजी हैं foo, जैसा कि आप किसी भी फ़ंक्शन घोषणा के साथ अपेक्षा करते हैं और क्योंकि वे सभी दायरे में हैं, वे सभी एक दूसरे के लिए उपयोग करने की आवश्यकता के बिना संदर्भित हैं this, जैसे आप एक फ़ंक्शन के साथ अपेक्षा करेंगे। अंतर यह है कि यह फ़ंक्शन एक ऑब्जेक्ट देता है जो निजी चर को उजागर करता है और उस ऑब्जेक्ट को असाइन करता है foo। अंत में, आप सिर्फ उस इंटरफ़ेस को वापस करते हैं जिसे आप return {}स्टेटमेंट के साथ ऑब्जेक्ट के रूप में एक्सपोज़ करना चाहते हैं ।

फिर फ़ंक्शन को अंत में निष्पादित किया जाता है ()जिसके कारण पूरे फू ऑब्जेक्ट का मूल्यांकन किया जाता है, सभी वेरिएबल्स को तत्काल और रिटर्न ऑब्जेक्ट के गुणों के रूप में जोड़ा जाता है foo()


14
इसे "बंद" कहना भ्रामक और भ्रामक है। यद्यपि किसी फ़ंक्शन से ओजबक्ट मान लौटाने वाले सटीक अर्थ पर राय अलग-अलग होती है, लेकिन किसी की पुस्तक में एक बंद का गठन नहीं होता है।

16

आप इसे इस तरह से कर सकते हैं

var a, b
var foo = {
    a: a = 5,
    b: b = 6,
    c: a + b
}

यह विधि मेरे लिए उपयोगी साबित हुई है जब मुझे उस वस्तु को संदर्भित करना था जिसे एक फ़ंक्शन मूल रूप से घोषित किया गया था। निम्नलिखित इसका एक न्यूनतम उदाहरण है कि मैंने इसका उपयोग कैसे किया:

function createMyObject() {
    var count = 0, self
    return {
        a: self = {
            log: function() {
                console.log(count++)
                return self
            }
        }
    }
}

स्वयं को उस ऑब्जेक्ट के रूप में परिभाषित करके जिसमें प्रिंट फ़ंक्शन होता है आप फ़ंक्शन को उस ऑब्जेक्ट को संदर्भित करने की अनुमति देते हैं। इसका मतलब है कि आपको किसी वस्तु को प्रिंट फ़ंक्शन को 'बाइंड' नहीं करना होगा यदि आपको इसे कहीं और पास करने की आवश्यकता है।

यदि आप, इसके बजाय, thisनीचे दिए गए उदाहरण के रूप में उपयोग करेंगे

function createMyObject() {
    var count = 0
    return {
        a: {
            log: function() {
                console.log(count++)
                return this
            }
        }
    }
}

फिर निम्न कोड 0, 1, 2 को लॉग करेगा और फिर एक त्रुटि देगा

var o = createMyObject()
var log = o.a.log
o.a.log().log() // this refers to the o.a object so the chaining works
log().log() // this refers to the window object so the chaining fails!

स्वयं की विधि का उपयोग करके आप गारंटी देते हैं कि प्रिंट हमेशा उसी वस्तु को लौटाएगा, जिस संदर्भ में फ़ंक्शन चलता है। ऊपर का कोड ठीक चलेगा और स्व के संस्करण का उपयोग करते समय 0, 1, 2 और 3 लॉग करें createMyObject()


3
अच्छे उदाहरण, सिवाय इसके कि आपने सभी अर्धविरामों को छोड़ दिया है।


9

पूरा होने के लिए, ES6 में हमें कक्षाएं मिली हैं (केवल नवीनतम ब्राउज़रों द्वारा इसे लिखने के समय समर्थित है, लेकिन Babel, टाइपस्क्रिप्ट और अन्य ट्रांसपैरर्स में उपलब्ध है)

class Foo {
  constructor(){
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
  }  
}

const foo = new Foo();

7

आप इसे मॉड्यूल पैटर्न का उपयोग करके कर सकते हैं। बिलकुल इसके जैसा:

var foo = function() {
  var that = {};

  that.a = 7;
  that.b = 6;

  that.c = function() {
    return that.a + that.b;
  }

  return that;
};
var fooObject = foo();
fooObject.c(); //13

इस पैटर्न के साथ आप अपनी ज़रूरत के हिसाब से कई फू ऑब्जेक्ट्स को इंस्टेंट कर सकते हैं।

http://jsfiddle.net/jPNxY/1/


2
यह मॉड्यूल पैटर्न का उदाहरण नहीं है, बस एक फ़ंक्शन है। यदि फू परिभाषा की अंतिम पंक्ति थी }();, तो यह एक फ़ंक्शन को निष्पादित करेगा और एक वस्तु को लौटाएगा। इसके अलावा, foo.cएक फ़ंक्शन है, इसलिए इसे क्लॉबर्स पर लिखना उस फ़ंक्शन और अगले आमंत्रण के माध्यम fooObject.c()से विफल हो जाएगा। हो सकता है कि यह फिडेल आपके करीब आने के करीब हो (यह एक सिंगलटन भी है, जिसे तत्काल तैयार नहीं किया गया है)।
हॉलिस्टर

2
"मॉड्यूल पैटर्न को मूल रूप से पारंपरिक सॉफ्टवेयर इंजीनियरिंग में कक्षाओं के लिए निजी और सार्वजनिक इनकैप्सुलेशन दोनों प्रदान करने के तरीके के रूप में परिभाषित किया गया था"। से: जावास्क्रिप्ट डिजाइन पैटर्न सीखना । वह वस्तु ऊपर वर्णित मॉड्यूल पैटर्न का पालन करती है, लेकिन शायद यह समझाने के लिए सबसे अच्छा नहीं है कि क्योंकि सार्वजनिक और निजी गुण / तरीके नहीं दिखा रहे हैं। यह एक jsfiddle.net/9nnR5/2 सार्वजनिक और निजी गुणों / विधियों के साथ एक ही वस्तु है। इसलिए दोनों इस पैटर्न का अनुसरण कर रहे हैं
राफेल रोचा

6

इसे पूरा करने के कई तरीके हैं; यह वह है जो मैं उपयोग करूंगा:

function Obj() {
 this.a = 5;
 this.b = this.a + 1;
 // return this; // commented out because this happens automatically
}

var o = new Obj();
o.b; // === 6

2
यह काम करता है, लेकिन वस्तु शाब्दिक अंकन के लाभों को समाप्त करता है।
kpozin

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

6

सिर्फ विचार के लिए - जगह के गुणों को समय रेखा से बाहर करें:

var foo = {
    a: function(){return 5}(),
    b: function(){return 6}(),
    c: function(){return this.a + this.b}
}

console.log(foo.c())

ऊपर भी बेहतर उत्तर हैं । इस तरह मैंने आपके साथ पूछताछ की उदाहरण कोड को संशोधित किया है।

अपडेट करें:

var foo = {
    get a(){return 5},
    get b(){return 6},
    get c(){return this.a + this.b}
}
// console.log(foo.c);

2
ES6 में आप इस सामान्य दृष्टिकोण को और अधिक सुरुचिपूर्ण बना सकते हैं: var foo = { get a(){return 5}, get b(){return 6}, get c(){return this.a + this.b} }इसलिए अब आप :) के foo.cबजाय बस कर सकते हैं foo.c()(बेझिझक पेस्ट करें कि आपके उत्तर में प्रारूपण बेहतर है!)

5

अपनी वस्तु शाब्दिक पर नए कार्य का सृजन और एक निर्माता को मूल समस्या से एक कट्टरपंथी प्रस्थान लगता है, और यह अनावश्यक है।

आप ऑब्जेक्ट शाब्दिक प्रारंभ के दौरान एक भाई की संपत्ति का संदर्भ नहीं दे सकते।

var x = { a: 1, b: 2, c: a + b } // not defined 
var y = { a: 1, b: 2, c: y.a + y.b } // not defined 

गणना की गई संपत्तियों के लिए सबसे सरल समाधान (कोई ढेर नहीं, कोई कार्य नहीं, कोई निर्माता नहीं):

var x = { a: 1, b: 2 };

x.c = x.a + x.b; // apply computed property

3

यहां पोस्ट किए गए अन्य उत्तर बेहतर हैं लेकिन यहां एक विकल्प है कि:

  • आरंभीकरण पर मान सेट करता है (एक गेटर, या व्युत्पन्न नहीं, आदि)
  • init()ऑब्जेक्ट शाब्दिक के बाहर किसी भी प्रकार या कोड की आवश्यकता नहीं है
  • एक वस्तु शाब्दिक है न कि कोई फैक्ट्री फ़ंक्शन या अन्य ऑब्जेक्ट क्रिएशन मैकेनिक।
  • कोई प्रदर्शन प्रभाव नहीं होना चाहिए (आरंभीकरण को छोड़कर)

स्वयं-निष्पादित अनाम फ़ंक्शंस और विंडो स्टोरेज

var foo = {
    bar:(function(){
        window.temp = "qwert";
        return window.temp;
    })(),
    baz: window.temp
};

आदेश की गारंटी ( barपहले baz) है।

यह windowनिश्चित रूप से प्रदूषित करता है, लेकिन मैं किसी ऐसी स्क्रिप्ट को लिखने की कल्पना नहीं कर window.tempसकता जिसे लगातार करने की आवश्यकता हो। शायद tempMyAppअगर तुम पागल हो।

यह बदसूरत भी है लेकिन कभी-कभी उपयोगी है। एक उदाहरण यह है कि जब आप कठोर आरंभिक स्थितियों के साथ API का उपयोग कर रहे होते हैं और ऐसा महसूस नहीं करते हैं कि स्कोरिंग सही है।

और यह सूखा है, बिल्कुल।


3

इस सब की कुंजी SCOPE है

आपको उस संपत्ति के "मूल" (मूल ऑब्जेक्ट) को एनकैप्सुलेट करना होगा, जिसे आप परिभाषित करना चाहते हैं क्योंकि यह स्वयं की त्वरित वस्तु है, और फिर आप कुंजी शब्द का उपयोग करके सिबलिंग संपत्तियों के संदर्भ बना सकते हैं। this

यह याद रखना बहुत महत्वपूर्ण है कि यदि आप thisपहली बार ऐसा किए बिना संदर्भित करते हैं, तो thisबाहरी दायरे को संदर्भित करेगा ... जो कि windowवस्तु होगी ।

var x = 9   //this is really window.x
var bar = {
  x: 1,
  y: 2,
  foo: new function(){
    this.a = 5, //assign value
    this.b = 6,
    this.c = this.a + this.b;  // 11
  },
  z: this.x   // 9 (not 1 as you might expect, b/c *this* refers `window` object)
};

2
यह मान्य जेएस भी नहीं है।

2

यदि आपकी वस्तु एक फ़ंक्शन के रूप में लिखी जाती है जो एक वस्तु लौटाता है, और आप ES6 ऑब्जेक्ट-विशेषता 'विधियों' का उपयोग करते हैं, तो यह संभव है:

const module = (state) => ({
  a: 1,
  oneThing() {
    state.b = state.b + this.a
  },
  anotherThing() {
    this.oneThing();
    state.c = state.b + this.a
  },
});

const store = {b: 10};
const root = module(store);

root.oneThing();
console.log(store);

root.anotherThing();
console.log(store);

console.log(root, Object.keys(root), root.prototype);

2

मैं वैकल्पिक के रूप में निम्न कोड का उपयोग करता हूं, और यह काम करता है। और चर भी सरणी जा सकता है। (@ फौस्टो आर।)

var foo = {
  a: 5,
  b: 6,
  c: function() {
    return this.a + this.b;
  },

  d: [10,20,30],
  e: function(x) {
    this.d.push(x);
    return this.d;
  }
};
foo.c(); // 11
foo.e(40); // foo.d = [10,20,30,40]

2

यहाँ एक साफ ES6 तरीका है:

var foo = (o => ({
    ...o,
    c: o.a + o.b
  }))({
    a: 5,
    b: 6
  });
  
console.log(foo);

मैं इसका उपयोग कुछ इस तरह से करने के लिए करता हूं:

const constants = Object.freeze(
  (_ => ({
    ..._,
    flag_data: {
      [_.a_flag]: 'foo',
      [_.b_flag]: 'bar',
      [_.c_flag]: 'oof'
    }
  }))({
    a_flag: 5,
    b_flag: 6,
    c_flag: 7,
  })
);

console.log(constants.flag_data[constants.b_flag]);


1

इस समाधान के बारे में यह कैसे नेस्टेड ऑब्जेक्ट्स के साथ सरणी के साथ भी काम करेगा

      Object.prototype.assignOwnProVal
     = function (to,from){ 
            function compose(obj,string){ 
                var parts = string.split('.'); 
                var newObj = obj[parts[0]]; 
                if(parts[1]){ 
                    parts.splice(0,1);
                    var newString = parts.join('.'); 
                    return compose(newObj,newString); 
                } 
                return newObj; 
            } 
            this[to] = compose(this,from);
     } 
     var obj = { name : 'Gaurav', temp : 
                  {id : [10,20], city:
                        {street:'Brunswick'}} } 
     obj.assignOwnProVal('street','temp.city.street'); 
     obj.assignOwnProVal('myid','temp.id.1');

0

एक विकल्प में फेंकने के बाद से मैंने इस सटीक परिदृश्य को कवर नहीं किया। यदि आप अद्यतन या अद्यतन नहीं करना चाहते हैं , तो एक ES6 IIFE अच्छी तरह से काम करता है।cab

var foo = ((a,b) => ({
    a,
    b,
    c: a + b
}))(a,b);

मेरी जरूरतों के लिए, मेरे पास एक ऐसी वस्तु है जो एक सरणी से संबंधित है जो कि लूप में उपयोग की जा रही है, इसलिए मैं केवल एक बार कुछ सामान्य सेटअप की गणना करना चाहता हूं, इसलिए यही मेरे पास है:

  let processingState = ((indexOfSelectedTier) => ({
      selectedTier,
      indexOfSelectedTier,
      hasUpperTierSelection: tiers.slice(0,indexOfSelectedTier)
                             .some(t => pendingSelectedFiltersState[t.name]),
  }))(tiers.indexOf(selectedTier));

चूंकि मुझे संपत्ति सेट करने की आवश्यकता है indexOfSelectedTierऔर संपत्ति सेट करते समय मुझे उस मूल्य का उपयोग करने की आवश्यकता है hasUpperTierSelection, मैं पहले उस मूल्य की गणना करता हूं और इसे आईआईएफई के लिए एक परम के रूप में पारित करता हूं।


0

अन्य दृष्टिकोण यह होगा कि इसमें गुण निर्दिष्ट करने से पहले वस्तु को पहले घोषित किया जाए:

const foo = {};
foo.a = 5;
foo.b = 6;
foo.c = foo.a + foo.b;  // Does work
foo.getSum = () => foo.a + foo.b + foo.c;  // foo.getSum() === 22

उसके साथ, आप पहले से ही दिए गए मानों तक पहुँचने के लिए ऑब्जेक्ट चर नाम का उपयोग कर सकते हैं। फ़ाइल के
लिए सर्वश्रेष्ठ config.js


यह एक आत्म संदर्भ नहीं है, बल्कि घोषित चर का संदर्भ है fooजो प्रश्न में ऑब्जेक्ट को इंगित करता है।
डेरेक हेंडरसन

0
var x = {
    a: (window.secreta = 5),
    b: (window.secretb = 6),
    c: window.secreta + window.secretb
};

यह @ स्लेडटॉडड के उत्तर के लगभग समान है, लेकिन एक फ़ंक्शन का उपयोग नहीं करता है।


-1

नोट: यह समाधान टाइपस्क्रिप्ट का उपयोग करता है (आप वेनिला जेएस का उपयोग कर सकते हैं जो टीएस यदि आवश्यक हो तो संकलित करता है)

class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };

    // this method is just to check/test this solution 
    check(){
        console.log(this.def.qwe);
    }
}

// these two lines are just to check
let instance = new asd();
instance.check();

यहाँ वर्ग अभिव्यक्ति का उपयोग कर रहे थे नेस्टेड वस्तु शाब्दिक इंटरफ़ेस हम चाहते हैं पाने के लिए। यह सृजन के दौरान किसी वस्तु के गुणों को संदर्भित करने में सक्षम होने के लिए अगली सबसे अच्छी बात IMHO है।

ध्यान देने वाली मुख्य बात यह है कि इस समाधान का उपयोग करते समय, आपके पास ठीक वैसा ही इंटरफ़ेस होता है जैसा कि आप किसी वस्तु शाब्दिक उपकरण से होता है। और वाक्य रचना अपने आप में एक वस्तु शाब्दिक (बनाम एक समारोह, आदि का उपयोग कर) के बहुत करीब है।

निम्नलिखित की तुलना करें

समाधान मैंने प्रस्तावित किया है

class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };

अगर वस्तु शाब्दिकता पर्याप्त होती तो समाधान

var asd = {
    def : {
        ads:'asd',
        qwe: this.ads + '123';, //ILLEGAL CODE; just to show ideal scenario
    }
}

एक और उदाहरण

यहाँ इस वर्ग में, आप आपस में कई सापेक्ष पथ जोड़ सकते हैं, जो किसी वस्तु शाब्दिक के साथ संभव नहीं है।

class CONSTANT {
    static readonly PATH = new class {
        /** private visibility because these relative paths don't make sense for direct access, they're only useful to path class
         *
         */
        private readonly RELATIVE = new class {
            readonly AFTER_EFFECTS_TEMPLATE_BINARY_VERSION: fs.PathLike = '\\assets\\aep-template\\src\\video-template.aep';
            readonly AFTER_EFFECTS_TEMPLATE_XML_VERSION: fs.PathLike = '\\assets\\aep-template\\intermediates\\video-template.aepx';
            readonly RELATIVE_PATH_TO_AFTER_EFFECTS: fs.PathLike = '\\Adobe\\Adobe After Effects CC 2018\\Support Files\\AfterFX.exe';
            readonly OUTPUT_DIRECTORY_NAME: fs.PathLike = '\\output';
            readonly INPUT_DIRECTORY_NAME: fs.PathLike = '\\input';
            readonly ASSETS_DIRECTORY_NAME: fs.PathLike = '\\assets';
        };
    }
}

2
क्या ऐसा हो सकता है क्योंकि आपका जवाब पूरी तरह से अप्रासंगिक है? मैं मानता हूं कि डाउनवोटर्स को समझाना चाहिए, लेकिन आपके उत्तर का सवाल से कोई लेना-देना नहीं है ...
मानगो जू

@ मानगो इसे इंगित करने के लिए धन्यवाद। ईमानदारी से, मैं ओपी के रूप में एक ही सवाल कर सकता हूं और मैंने सुझाए गए समाधान का उपयोग किया है। अनिश्चित, क्यों इसे अप्रासंगिक माना जा रहा है। यदि आपके पास समय है, तो कृपया समझाएं ताकि मैं उत्तर को बेहतर बना सकूं या कम से कम जान सकूं कि मैं कहां गलत हूं। मैं दुर्भाग्य से, यह नहीं समझ रहा हूं कि यह एक उचित समाधान क्यों नहीं है।
धीरज भास्कर

-2

यदि आप देशी जेएस का उपयोग करना चाहते हैं, तो अन्य उत्तर अच्छे समाधान प्रदान करते हैं।

लेकिन अगर आप स्व-संदर्भित वस्तुओं को लिखने के लिए तैयार हैं जैसे:

{ 
  a: ...,
  b: "${this.a + this.a}",
}

मैंने एक एनपीएम लाइब्रेरी लिखी जिसे सेल्फ रेफरेंस-ऑब्जेक्ट कहा जाता है जो उस सिंटैक्स का समर्थन करता है और एक मूल ऑब्जेक्ट लौटाता है।


1
कृपया केवल उत्तरों से लिंक से बचें । उत्तर जो "किसी बाहरी साइट के लिंक से बमुश्किल अधिक हैं" को हटाया जा सकता है
क्वेंटिन

@ आपके पास कोई सुझाव है कि मैं अपने उत्तर को कैसे बेहतर बना सकता हूं? इस प्रश्न के अन्य उत्तर कवर करते हैं कि आप देशी जावास्क्रिप्ट में स्व-संदर्भित वस्तुओं को लिखने में कैसे सक्षम हो सकते हैं, लेकिन यदि आप स्वयं-संदर्भित वस्तुओं को सिंटैक्स के साथ सिंटैक्स के समान लिखना चाहते हैं तो मूल प्रश्न मुझे लगता है कि पुस्तकालय मैंने लिखा कि दूसरों के लिए उपयोगी हो सकता है एक समाधान की तलाश में। कुछ प्रतिक्रिया पाने के लिए खुश।
एलेक्स-ए-लियोन

यहां सुधारने के लिए युगल बातें सबसे पहले, और सबसे स्पष्ट रूप से, आप बिना बैक टिक्स के टेम्पलेट शाब्दिक वाक्यविन्यास का उपयोग कर रहे हैं। आपका bसंपत्ति के मूल्य होना चाहिए: ${this.a + this.a}। दूसरा, लेकिन कम महत्वपूर्ण बात, आप एक नंबर वापस करना चाहते हैं, न कि कुछ का उपयोग करके एक स्ट्रिंग parseInt। अंतिम और सबसे महत्वपूर्ण, जब मैंने इस उदाहरण की कोशिश की तो यह बस काम नहीं करता है, उसी कारण से ओपी पूछ रहा है। thisरिटर्न जब अपनी ही वस्तु घोषणा इस्तेमाल किया अपरिभाषित। @ एलेक्स-ए-लियोन
एलेक डोनाल्ड

@AlecDonaldMather - समय निकालने और कुछ प्रतिक्रिया प्रदान करने के लिए धन्यवाद! यदि आप इस परियोजना में रुचि रखते हैं, तो इस चर्चा को गीथब पर ले जाना बेहतर हो सकता है, लेकिन आपकी प्रतिक्रिया का कुछ जवाब देने के लिए: - बैकटिक्स का उपयोग करना: जैसा कि पिछली टिप्पणियों में बताया गया है, यह सिंटैक्स is JS द्वारा समर्थित है, और इसलिए इसके बजाय स्ट्रिंग्स का उपयोग करना बैकस्टिक्स की आवश्यकता यहाँ है, क्योंकि जेएस से परिभाषित करने से पहले "इसे" को हल करने की कोशिश करने वाले जेएस से बचने के लिए - एक नंबर वापस करना, यह काम करना चाहिए अगर a + b पहले से ही नंबर हैं, क्योंकि a + b एक नंबर लौटाएगा यदि a और b दोनों हैं पहले से ही संख्या।
एलेक्स-ए-लियोन

इसे अपरिभाषित करके लौटें, क्या आप बता सकते हैं कि आपने पुस्तकालय का उपयोग करने की कोशिश कैसे की? ऐसा नहीं होना चाहिए, लेकिन शायद एक किनारे का मामला है जिसे मैंने छोड़ दिया है? उस ने कहा, यह पुस्तकालय पूरी तरह से मुद्दे को हल नहीं करता है, और इसके पास ट्रेडऑफ का एक सेट है, लेकिन अगर आप इसे बेहतर बनाने में मेरी मदद कर रहे हैं / इसका उपयोग करें तो मुझे बताएं!
एलेक्स-ए-लियोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.