2010-09-22 13 views
8

मैं ऑब्जेक्ट्स के साथ ऑब्जेक्ट बनाने के लिए ऑब्जेक्ट शाब्दिक का उपयोग कर रहा था।
यहां एक साधारण उदाहरण है।जावास्क्रिप्ट ऑब्जेक्ट शाब्दिक: मूल्य प्रारंभिकरण?

var SizeManager = { 
    width : 800, 
    height : 600, 
    ratio : this.width/this.height, 
    resize : function (newWidth) { 
     width = newWidth; 
     height = newWidth/ratio; 
    } 
} 

मेरे मुद्दा यह है कि SizeManager.ratio रिटर्न "NaN" है। मुझे पूरा यकीन है कि यह एक प्रारंभिक मुद्दा है।
क्या सही अनुपात मूल्य प्राप्त करने का कोई तरीका है?
क्या ऑब्जेक्ट को किसी ऑब्जेक्ट को एक ठेकेदार या प्रारंभकर्ता असाइन करने का कोई तरीका है?
एक कन्स्ट्रक्टर objcet को एकमात्र तरीका परिभाषित कर रहा है?

संपादित करें: ऑफ कोर्स आकार प्रबंधक एक सिंगलटन (केवल एक वस्तु) है, इस तरह मैं ऑब्जेक्ट शाब्दिक का उपयोग कर रहा था।

उत्तर

24

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

(मैं इस के अंत में अपने विशिष्ट उदाहरण से इस बारे में कुछ ratio ने बताया है, लेकिन पहले के सामान्य मामले आप को बढ़ाने के लिए कुछ विकल्प के माध्यम से चलना करते हैं।)

Daniel's given you बनाने पर एक अच्छा स्टीयर ratio एक फ़ंक्शन को छोड़कर ऐसा लगता है कि आप चौड़ाई को बदलना नहीं चाहते हैं। या फिर, यदि width और height बदलने के लिए नहीं जा रहे हैं, बस इसे बाद में गणना:

var SizeManager = { 
    width : 800, 
    height : 600, 
    resize : function (newWidth) { 
     this.width = newWidth; 
     this.height = newWidth/this.ratio; 
    } 
}; 
SizeManager.ratio = SizeManager.width/SizeManager.height; 

(साइड नोट: मैं गुण आप resize में संदर्भित कर रहे हैं करने के लिए this. जोड़ दिया है वे अपने मूल से लापता हैं। ।, लेकिन वे आवश्यक उनके बिना, आप horror of implicit globals है, जो एक बुरा बात (टीएम) साथ काम कर रहे हैं)

बेशक

, आप एक कारखाने में है, उन सभी को संपुटित सकता है:।

function makeSizeManager(width, height) { 
    return { 
     width : width, 
     height : height, 
     ratio : width/height, 
     resize : function (newWidth) { 
      this.width = newWidth; 
      this.height = newWidth/this.ratio; 
     } 
    }; 
} 
var SizeManager = makeSizeManager(800, 600); 

... लेकिन फिर आप के रूप में अच्छी ताकि आप डुप्लिकेट (लेकिन समान) के बहुत सारे नहीं बनाते हैं यह एक वास्तविक निर्माता समारोह बना सकता है resize कार्य:

function SizeManager(width, height) { 
    this.width = width; 
    this.height = height; 
    this.ratio = width/height; 
} 
SizeManager.prototype.resize = function (newWidth) { 
    this.width = newWidth; 
    this.height = newWidth/this.ratio; 
}; 
var aSizeManagerInstance = new SizeManager(800, 600); 

(ध्यान दें मैं थोड़ा पर नाम बदल यह आखिरी वाला)

और एक आखिरी अंतिम नोट के रूप में: अपने विशिष्ट उदाहरण में, आप वास्तव में सब पर ratio स्टोर करने के लिए की जरूरत नहीं है, तो आप ऐसा कर सकते हैं:

var SizeManager = { 
    width : 800, 
    height : 600, 
    resize : function (newWidth) { 
     var ratio = this.width/this.height; 
     this.width = newWidth; 
     this.height = newWidth/ratio; 
    } 
}; 

लेकिन वह सिर्फ इतना है कि विशिष्ट उदाहरण के लिए है, इसलिए सामान्य मामले के बारे में बात करने के लिए ऊपर चर्चा।

+2

यदि आप किसी ऑब्जेक्ट से किसी फ़ंक्शन में इसे बदल रहे हैं, तो आपको गुण निर्दिष्ट करने के तरीके को बदलने की आवश्यकता है (कोड के तीसरे ब्लॉक में)। अर्थात। 'this.width = width' की बजाय' width: width' –

+0

@ Daniel: धन्यवाद! ऐसा लगता है कि पेस्ट करने के बाद मैंने केवल उन पंक्तियों को आधा संपादित किया था। फिक्स्ड। –

5

आपका ratio संपत्ति वास्तव में एक विधि होना चाहिए आप इसे width और height में परिवर्तन के आधार पर बदलना चाहते हैं:

var SizeManager = { 
    width : 800, 
    height : 600, 
    ratio : function() { 
     return this.width/this.height; 
    }, 
    resize : function (newWidth) { 
     width = newWidth; 
     height = newWidth/ratio; 
    } 
} 

इसके अलावा, आप शायद में this.width और this.height बजाय width और height का उल्लेख करना चाहते हैं resize विधि।

+0

आकार समारोह में, '' ratio' this.ratio() ' –

+0

तो अनुपात एक पद्धति के लिए परिवर्तित किया जाना चाहिए करने के लिए बदलने की आवश्यकता है और एक संपत्ति नहीं हो सकता। सही? – bonfo

+0

@ जोश मैंने आकार बदलने की विधि नहीं बदली, मैं इसे ओपी में छोड़ दूंगा। यद्यपि इसमें चौड़ाई बदलने से पहले पुराने अनुपात को कैश करना सबसे अच्छा होगा, क्योंकि 'अनुपात' एक समारोह होने के साथ, 'this.width' के बाद मान बदल जाएगा। –

0

एक वस्तु शाब्दिक में, this केवल वस्तु शाब्दिक खुद को संदर्भित करता है जब यह एक समारोह के अंदर है। आप किसी ऑब्जेक्ट के बजाय इस तरह कुछ कोशिश कर सकते हैं; this उस ऑब्जेक्ट का संदर्भ देगा जो आप कार्यों के अंदर और बाहर दोनों बना रहे हैं।

var SizeManager = new function(){ 
    this.width = 800; 
    this.height = 600; 
    this.ratio = this.width/this.height; 
    this.resize = function (newWidth) { 
     this.width = newWidth; 
     this.height = newWidth/this.ratio; 
    } 
} 

यह सिंगलटन पैटर्न के लिए काम करेगा। यदि आपको एक से अधिक आकार प्रबंधक की आवश्यकता है, तो इसे किसी ऑब्जेक्ट के बजाय एक कन्स्ट्रक्टर फ़ंक्शन बनाएं।

function SizeManager (w, h){ 
    w && (this.width=w); 
    h && (this.height=h); 
    this.ratio = this.width/this.height; 
} 
SizeManager.prototype={ 
    width: 800, 
    height: 600, 
    resize: function (newWidth) { 
    this.width = newWidth; 
    this.height = newWidth/this.ratio; 
    } 
} 
+0

* "ऑब्जेक्ट में शाब्दिक, 'यह केवल उस क्रिया को संदर्भित करता है जब यह किसी फ़ंक्शन के अंदर होता है।" * आपके कोड स्निपेट में ** कोई ऑब्जेक्ट शाब्दिक ** नहीं है। एक कन्स्ट्रक्टर फ़ंक्शन है, जिसे आप तुरंत 'नए' के ​​माध्यम से कॉल कर रहे हैं, लेकिन कोई ऑब्जेक्ट शाब्दिक नहीं है। कन्स्ट्रक्टर फ़ंक्शन के अंदर, 'यह' फ़ंक्शन को कॉल करने के हिस्से के रूप में 'new' द्वारा बनाई गई नई ऑब्जेक्ट को संदर्भित करता है। –

+0

'आकार बदलें' कॉल करने के बाद, 'अनुपात' गलत –

+0

@ टी.जे. होगा। पाउडर: मैं अपने कोड में शाब्दिक वस्तु के बारे में बात कर रहा था, मेरा नहीं, जाहिर है, क्योंकि मेरे पास एक नहीं है, जैसा कि आप बताते हैं। संदर्भ, आदमी। –

संबंधित मुद्दे