2012-02-28 12 views
10

मैं हाल ही में node.js के साथ टकरा रहा हूं और मैं मॉड्यूल के वैश्विक दायरे में this के उपयोग के बारे में एक अजीब व्यवहार में भाग गया।node.js: वैश्विक दायरे में 'इस' का भ्रमित उपयोग

this वैश्विक क्षेत्र में module.exports के लिए बाध्य है:

console.log(this === exports); // -> true 

लेकिन this एक विधि दायरे में वैश्विक के लिए बाध्य है:

(function() { console.log(this === global); })(); // -> true 

यह भी इस उलझनपूर्ण व्यवहार हो:

this.Foo = "Weird"; 
console.log(Foo); // -> throws undefined 

(function() { this.Bar = "Weird"; })(); 
console.log(Bar); // -> "Weird" 

मुझे लगता है कि समाधान टी नहीं है o वैश्विक दायरे में this का कभी भी उपयोग न करें और इसके बजाय extends या global का उपयोग करें, लेकिन क्या यह सब के पीछे एक तर्क है या यह node.js में एक बग या सीमा है?

उत्तर

1

एक साधारण कॉमनजेएस मॉड्यूल कार्यान्वयन पर काम करने में, मुझे यह सोचना पड़ा कि मॉड्यूल के वैश्विक दायरे में this के साथ क्या करना है; यह spec द्वारा संबोधित नहीं है।

मैं भी पहली बार में exports वस्तु के रूप में इसे सेट अप क्योंकि मैंने सोचा कि उपयोगी होगा, लेकिन बाद में found some code मैं जरूरत "Modulize" कि this उपयोग कर रहा था वैश्विक ऑब्जेक्ट में एक संभाल पाने के लिए, करने के लिए तो मैं this बदल मॉड्यूल कोड के लिए जितना संभव हो सके "सामान्य" वातावरण के करीब प्रदान करने के लिए वैश्विक वस्तु पर वापस जाएं।

हम केवल अनुमान लगा सकते हैं कि नोड जिस तरह से स्थापित है (या लेखक से पूछता है), लेकिन मेरा अनुमान है कि यह एक उपयोगी विचार जैसा प्रतीत होता है, जिस तरह से आप module दे सकते हैं नोड में exports संपत्ति ऑब्जेक्ट करें और इसे मॉड्यूल के वास्तविक exports में प्रतिबिंबित करें (यह व्यवहार भी spec का हिस्सा नहीं है, लेकिन इसके खिलाफ भी नहीं जाता है)।

thisglobal संदर्भ में आपके प्रश्न के हिस्से के रूप में, अन्य उत्तरों की व्याख्या के अनुसार, यह this काम करता है; यह एक नोड-विशिष्ट व्यवहार नहीं है, यह एक अजीब जावास्क्रिप्ट व्यवहार है।

7

उसके पीछे "तर्क" यह है कि this का मान हमेशा पर निर्भर करता है कि एक फ़ंक्शन कैसे लागू किया जाता है

आपके मामले में, आपके पास एक स्व-निष्पादन अनाम कार्य है, वहां this हमेशा वैश्विक वस्तु (गैर सख्त मोड) या undefined (ES5 सख्त) का संदर्भ देता है।

आप "बाहरी" this मूल्य उपयोग करना चाहते हैं, तो आप या तो एक संदर्भ है कि समारोह निष्पादित करने से पहले संग्रहीत कर सकती है,

var outerScope = this; 

(function() { outerScope.Bar = "Weird"; })(); 
console.log(Foo); // -> throws undefined 

की तरह या .bind() फिर कार्यों दायरे अपने आप को,

(function() { this.Bar = "Weird"; }).bind(this)(); 
की तरह
+1

यदि वैश्विक स्तर पर 'यह' 'विस्तार 'के बजाय' वैश्विक 'तक सीमित था तो यह कम भ्रमित नहीं होगा? मैं उम्मीद करता हूं कि 'वैश्विक' का मतलब वैश्विक दायरे और स्थिर कार्यक्षेत्र में भी होगा। –

+0

@ सेल्फलेस कोडर: मैं ईमानदारी से नहीं जानता कि यह 'निर्यात' वस्तु से क्यों जुड़ा हुआ है। लेकिन आम तौर पर यह एक अच्छा विचार है कि वैश्विक वस्तु को डेटा के साथ छेड़छाड़ न करें। इसलिए, केवल ध्यान रखें कि किसी भी फ़ंक्शन-संदर्भ में इसे अलग-अलग 'यह' मान हो सकता है, इस पर निर्भर करता है कि इसे कैसा कहा जाता है। – jAndy

+0

जैसा कि जैंडी कहते हैं, यह मूल रूप से जावास्क्रिप्ट में कैसे काम करता है। मैंने इस पर कोई चर्चा नहीं पढ़ी है, लेकिन मुझे लगता है कि वैश्विक दायरे में 'यह === निर्यात' होने पर ब्राउज़र में वैश्विक दायरे में '=== विंडो 'के अनुरूप होना चाहिए। आईएमओ, वैश्विक दायरे में 'यह === वैश्विक' होने से कम समझ में आता है, क्योंकि इसका मतलब यह होगा कि 'this.foo === foo'। –

1

मुझे नहीं पता कि यह नोड.जेएस टीम का सही इरादा है, लेकिन अगर यह नहीं था तो मुझे आश्चर्य होगा। इस उदाहरण पर विचार करें ब्राउज़र के dev console में भाग गया (उदा।क्रोम):

var x = function(){console.log(this)} 
a = {} 
a.x = x 
a.xx = function(){x()} 

a.x() 
>> Object 
a.xx() 
>> DOMWindow 
x() 
>> DOMWindow 

आप उसके संदर्भ निर्दिष्ट किए बिना एक विधि को क्रियान्वित देख सकते हैं संदर्भ वैश्विक एक होने का सेट। इस मामले में DOMWindow ऑब्जेक्ट।

जब आप मॉड्यूल के अंदर होते हैं तो आपका संदर्भ मॉड्यूल होता है, लेकिन इसमें .call या .apply या obj के साथ संदर्भ निर्दिष्ट किए बिना किसी विधि को निष्पादित किया जाता है। स्थानीय संदर्भ, module.exports के बजाय वैश्विक संदर्भ, global का उपयोग करेगा।

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