2011-02-02 9 views
12

में जावास्क्रिप्ट में कोई प्रभाव नहीं है, this को इसकी गुणों का उपयोग करते समय हमेशा स्पष्ट रूप से बताया जाना चाहिए। उदाहरण के लिए:जावास्क्रिप्ट

function Frobber(x) { 
    this.x = x; 
    return this; 
} 

Frobber.prototype.frob = function() { 
    // wrong: 
    return x * x; 
    // right: 
    return this.x * this.x; 
} 

मुझे पता है मैं with(this) (जो अब मान्य नहीं है और आम तौर पर पर सिकोड़ी) का उपयोग कर सकते हैं, लेकिन क्यों दायरे में this के गुणों स्वचालित रूप से नहीं कर रहे हैं? मैं सोच रहा हूं कि इस डिजाइन के फैसले का एक कारण होना चाहिए।

+0

मुझे वास्तव में पता नहीं है लेकिन मैं बस पढ़ने योग्यता के लिए अनुमान लगाऊंगा। एक और यादृच्छिक अनुमान यह होगा कि यह एक व्याख्या की गई भाषा में परिवर्तनीय संकल्प में गति की चीजों की मदद कर सकता है? – madmik3

+0

शायद यह डिज़ाइन था ताकि प्रोटोटाइप श्रृंखलाओं के बहुत से होने पर भी वैश्विक दायरे को आसानी से पहुंचा जा सके ?! – kjy112

+0

@ kjy112: न केवल वैश्विक - प्रत्येक संलग्न क्षेत्र। बंद के साथ विशेष रूप से महत्वपूर्ण है। – delnan

उत्तर

9

यह पायथन में समान है। कारण काफी सरल है: नहीं जोड़ सकता है, क्योंकि यह बाहरी क्षेत्रों में गैर-स्थानीय चर के लिए खोज करने के डिफ़ॉल्ट स्कॉइंग नियम के साथ संघर्ष करता है। सांख्यिकीय रूप से टाइप की गई भाषाओं में यह संभव है, क्योंकि this के सदस्य संकलित समय पर ज्ञात हैं।

और क्या करता है, तो यह एक गतिशील निर्णय लिया, इस तरह के रूप में (या जो रनटाइम के दौरान निर्णय लिया गया है इस के लिए किसी भी अन्य नियम) "xthis.x अगर this.x !== undefined और अन्यथा चर x करने का अर्थ है"? यह बहुत खतरनाक है, क्योंकि यह this पर आधारित स्थानीय चर को छाया कर सकता है, यानी कुछ वस्तुओं के लिए पूरी तरह वैध कोड तोड़ना। एक और मुद्दा: undeclaredVar = ... एक नया उदाहरण विशेषता जोड़ें? यदि नहीं, तो यह अंतर्निहित और स्पष्ट this के बीच एक बदसूरत असमानता होगी। यदि यह एक आवृत्ति विशेषता बनाता है, तो आप अंदरूनी कार्यों से वैश्विक और बंद चर को सेट करने की क्षमता खो देंगे - बहुत अधिक नुकसान नहीं, कई लोग कहेंगे; लेकिन जेएस डिजाइनरों ने अन्यथा सोचा है, क्योंकि उन्होंने डिफ़ॉल्ट रूप से वैश्विक दायरा चुना है।

"आकस्मिक चर" बनाना छाया उदाहरण विशेषताओं को कम खतरनाक होगा, लेकिन बहुत सारे नामों से भरे घोंसले वाले घोंसले के साथ, आप संभावित रूप से this. का उपयोग ज्यादातर मामलों में करने के लिए मजबूर होना चाहते हैं - इसलिए नेट जीत कम है। इसके लिए, और/या अन्य कारणों से, डिजाइनरों को एक शॉर्टकट अक्षम माना जाता है।

1

यदि xthis.x होने के लिए निहित है, तो आप x नाम के रूप में परिभाषित चर का उपयोग कैसे करेंगे?

function Frobber(x) { this.x = x; } 
Frobber.prototype.frob = function() { 
    var x = 'WHAT ABOUT ME'; 
    return x; 
} 
+3

अन्य भाषाओं में ठीक काम करता है। स्थानीय चर छाया वस्तु गुण। – kprevas

+0

उल्लेख नहीं है, जैसा कि @ kjy112 ने बताया है, वैश्विक दायरे से चर। – harpo

+0

@kprevas: इनमें से कोई गतिशील भाषाएं? मुझे कोई नहीं पता (पायथन नहीं है, रूबी अंक उदाहरण @ @ 'के साथ विशेषता है, मुझे पर्ल का कोई अंदाज़ा नहीं है, स्मॉलटॉक-आईएसएच भाषाएं 'ऑब्जेक्ट स्लॉट' जैसी कुछ चीज़ों का उपयोग करती हैं, जहां तक ​​मुझे पता है)। – delnan

2

जावास्क्रिप्ट में "यह" क्या संदर्भित करता है पूरी तरह से वर्तमान फ़ंक्शन को कैसे कॉल किया गया है इसका एक कार्य है।

यदि इसे विधि (यानी ऑपरेटर के साथ) कहा जाता है तो 'यह' बिंदु से पहले ऑब्जेक्ट पर सेट हो जाएगा।

यदि इसे एक साधारण कार्य के रूप में जाना जाता है, तो 'यह' वैश्विक वस्तु (आमतौर पर खिड़की) होगी।

आईआईआरसी यदि आप Function.call का उपयोग करते हैं, तो आप इसे स्पष्ट रूप से सेट कर सकते हैं।

जावास्क्रिप्ट एक ओओ भाषा है लेकिन कक्षाएं नहीं है, और (सख्ती से) विधियों के पास नहीं है।

+3

सही है, लेकिन यह सवाल से कैसे संबंधित है? – delnan

+0

क्योंकि उन उदाहरणों में 'यह' क्या बाध्य है, इस पर निर्भर करेगा कि कार्यों को कैसे कहा जाता है। –

1

आप स्पष्ट रूप से निर्दिष्ट करने के लिए "यह" क्योंकि "खिड़की" निहित है बजाय

कोड

function SomeFunc(x) { 
    y = x; 
    return this; 
} 

रूप

function SomeFunc(x) { 
    window.y = x; 
    return this; 
} 
1

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

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

चूंकि आप किसी ऑब्जेक्ट में गतिशील रूप से नई गुण जोड़ सकते हैं, तो आपको यह भी सुनिश्चित करना होगा कि आपके द्वारा जो भी नई संपत्ति आप जोड़ती है, वह सभी ऑब्जेक्ट विधियों में उन सभी पैरामीटर, चर, ... के साथ टकराव नहीं करती है।

इससे निपटना लगभग असंभव होगा।

0

JavaScript: The Good Parts (Functions -- Invocation) से:

जावास्क्रिप्ट में मंगलाचरण के चार पैटर्न होते हैं: विधि मंगलाचरण पैटर्न, समारोह मंगलाचरण पैटर्न, निर्माता मंगलाचरण पैटर्न, और मंगलाचरण पैटर्न लागू होते हैं।

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

+1

वास्तव में, लेकिन 'यह' अभी भी सवाल का जवाब नहीं देता है ... – configurator

+0

यह प्रश्न का उत्तर कैसे नहीं देता है? जब तक आप फ़ंक्शन का आह्वान नहीं करते हैं, तब तक संदर्भ परिभाषित नहीं किया जाता है, और यह इस बात पर निर्भर करता है कि आप कैसे कार्य को परिभाषित करते हैं कि यह कैसे परिभाषित किया जाता है।इसलिए, आप यह नहीं जान सकते कि यह कार्य तब तक नहीं है जब तक कि फ़ंक्शन लागू नहीं किया जाता है। –