2012-11-16 20 views
5

मैं ES6 में अपने आप को देख मसौदा की कोशिश की है, लेकिन मैं देखने के लिए जहां यकीन नहीं है:`ECMAScript में वैश्विक क्षेत्र में this` 6

कोई मुझे बता सकते हैं कि ES6 में this जरूरी वैश्विक को संदर्भित करता है आपत्ति? साथ ही, क्या इस ऑब्जेक्ट में वैश्विक दायरे के समान सदस्य होंगे?

यदि आप ES5 के लिए उत्तर दे सकते हैं जो सहायक भी होगा।

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


अपडेट - क्यों मैं जानना चाहता हूँ: मैं मूल रूप से यह पता लगाने की कैसे ES5 & 6. मैं क्योंकि है कि ब्राउज़र के लिए विशिष्ट है window पर भरोसा नहीं कर सकते में मज़बूती से वैश्विक वस्तु पाने के लिए कोशिश कर रहा हूँ, न ही मैं global पर भरोसा कर सकता हूं क्योंकि यह नोड जैसे वातावरण के लिए विशिष्ट है। मुझे पता है कि नोड में this मॉड्यूल स्कोप में module का संदर्भ दे सकता है, लेकिन मुझे लगता है कि यह अभी भी वैश्विक क्षेत्र में global को संदर्भित करता है। मैं एक वैश्विक पर्यावरण प्राप्त करने के लिए एक क्रॉस-एनवायरनमेंट ES5 & 6 अनुपालन तरीका चाहता हूं (यदि संभव हो)। ऐसा लगता है कि वैश्विक वातावरण में this के सभी वातावरण में मुझे लगता है कि, लेकिन मैं जानना चाहता हूं कि यह वास्तविक कल्पना का हिस्सा है (और किसी भी पर्यावरण में इतना विश्वसनीय है कि मैं परिचित नहीं हूं)।

मुझे यह भी जानने की जरूरत है कि क्या वैश्विक क्षेत्र और वैश्विक वस्तु spec द्वारा एक ही चीज़ है। दूसरे शब्दों में वैश्विक दायरे में सभी चर globalobject.variable_name के समान होंगे?


अद्यतन 2 - मुझे क्या करना कोशिश कर रहा हूँ:

मैं कुछ ES6 shims for ES5 environments विकसित किया है। मैं यह जानने के लिए सबसे अच्छा तरीका जानना चाहता हूं कि (1) यह देखने के लिए जांचें कि क्या ईएस 6 बिल्ट-इन्स पहले से मौजूद हैं या नहीं, ताकि जब संभव हो तो मेरे शिम्स की बजाय उनका उपयोग किया जा सके, और (2) मेरे शिम को वैश्विक दायरे में जोड़ें यदि निर्मित- इन पहले से मौजूद नहीं है।

वर्तमान में मैं इस पैटर्न अनुसरण कर रहा हूं:

(function() { 

    // Indirect eval to run in global scope. 
    // (We get whatever "this" is in global scope, hoping that it's the global object... 
    // Whether this line does what I want it to is the crux of my question.) 
    var global = (0, eval)('this'); 

    // If Symbol does not already exist in global scope, 
    if (!global.Symbol) 

     // Then add Symbol to global scope. 
     global.Symbol = (function() { 

      // ... 
      // Return my Symbol shim 

     })(); 

})(); 

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

मुझे पता चला है कि, ES5 spec द्वारा, अप्रत्यक्ष eval वैश्विक दायरे में कोड निष्पादित करता है। तो मैं कम से कम ऐसा करने में सक्षम हूं। मेरे प्रश्न हैं यदि मुझे वैश्विक दायरे में this मिलते हैं, (1) उस वस्तु के गुणों की जांच करना मुझे बताएगा कि अंतर्निहित वैश्विक क्षेत्र में पहले से मौजूद है या नहीं? और (2) उस ऑब्जेक्ट में गुण जोड़ना मुझे वैश्विक दायरे में चर जोड़ने की अनुमति देता है?

+3

यह पिछले ES चश्मे की तरह काम करना चाहिए क्योंकि यह 'ईएसई विशिष्ट नहीं है। 'इस' का अर्थ इस बात पर निर्भर करता है कि इसका उपयोग कहां किया जाता है, और यह हमेशा वैश्विक वस्तु नहीं है। – Jay

+0

समझा; यही कारण है कि मैंने "वैश्विक दायरे में" पूछा, जहां ब्राउज़र में 'यह' 'विंडो 'जैसा ही है जो वैश्विक वस्तु भी है। मुझे नहीं पता, हालांकि, अगर यह ईएस में निर्दिष्ट है या यदि यह भाषा के लिए सिर्फ ब्राउज़र एक्सटेंशन है। –

+1

जब तक आप एसईएस की तरह कुछ नहीं हैं, अप्रत्यक्ष eval चाल विश्वसनीय रूप से काम करेगा। एक बार आपके पास वैश्विक वस्तु हो जाने के बाद आप इसे असाइन कर सकते हैं और गुणों की जांच कर सकते हैं और यह वही करेगा जो आप चाहते हैं। ईएस 6 में, एंड्रियास ने चलो, कॉन्स इत्यादि के बारे में क्या कहा, इसके अलावा मॉड्यूल के मामले में भी अपनी निजी वैश्विक स्थिति है, जिसमें मुख्य वैश्विक वस्तु बाहरी दायरे के रूप में है, इसलिए बाहरी वैश्विक तक पहुंच या संशोधित करना असंभव है इसे प्रदान किया जाता है (जैसे node.js स्वचालित रूप से 'वैश्विक' को परिभाषित करते हैं, उदाहरण के लिए, आपको उस बाहरी वैश्विक का संदर्भ देगा)। –

उत्तर

2

हां, this वैश्विक दायरे में ईएस 6 में वैश्विक वस्तु का उल्लेख जारी रहेगा। (आम तौर पर, ईएस 6 पूरी तरह से पीछे की ओर संगत होने वाला माना जाता है, यानी ईएस 5 में काम करने की गारंटी देने वाले किसी भी कोड को ईएस 6 में भी काम करना चाहिए)।

हालांकि, "वैश्विक क्षेत्र" की धारणा ईएस 6 में वैश्विक वस्तु के समान नहीं होगी। यह नए घोषणापत्रों को प्रस्तुत करता है जो व्याख्यात्मक रूप से स्कॉप्ड (let, const, class, module और कुछ और हैं)। आखिरी बैठक में निष्कर्ष यह था कि इनमें से कोई भी वैश्विक वस्तु के गुणों के रूप में दिखाई नहीं देगा। इसके लिए कई तकनीकी और पद्धतिपरक कारण हैं, लेकिन नीचे की रेखा यह है कि वैश्विक वस्तु का पूरी तरह से उपयोग करने से बचने के लिए सबसे अच्छा है (यह हमेशा सच रहा है, लेकिन ईएस 6 में भी अधिक है)।

क्या कुछ विशिष्ट है जिसके लिए आपको वैश्विक वस्तु की आवश्यकता है?

+0

हे एंड्रियास, आपकी विशेषज्ञता की पेशकश के लिए धन्यवाद! मैंने आपके प्रश्न का उत्तर दिया है कि मैं अपनी मूल पोस्ट के ** अपडेट 2 ** में वैश्विक वस्तु क्यों चाहता हूं। क्या आप एक नज़र डाल सकते हैं और देख सकते हैं कि मैं जिस पैटर्न का अनुसरण कर रहा हूं वह अच्छा है? धन्यवाद! –

0

अधिकांशतः हाँ।

किसी भी गैर-वस्तु में this पासिंग (या गैर सेट this) वैश्विक वस्तु का उल्लेख होगा:

(function(global){ /* do stuff! */ }(this)); 

यह व्यवहार (समझा जा पिछड़े संगतता के मुद्दों के लिए) ES6 में रहने का इरादा है। और इस तरह से अधिकांश मल्टीप्लाफ्फ़्ट (ब्राउज़र/नोड) प्लगइन्स जिन्हें मैं जानता हूं, वैश्विक वस्तु तक पहुंच रहे हैं। उदाहरण के लिए: https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

हालांकि, यह सच है कि सर्वर पर प्लगइन केवल thismodule (जिसे निर्यात किया जाता है) के रूप में उपयोग करता है। लेकिन, यही वह है जो आप नोड में चाहते हैं। आपकी वैश्विक जगह कभी भी साफ नहीं होती है (अगर मैन्युअल रूप से किया जाता है, या सर्वर पुनरारंभ करने के अलावा)। तो यह सभी ग्राहक कनेक्शन के बीच साझा किया जाता है; वैश्विक अंतरिक्ष में कुछ भी असाइन करना वास्तव में एक अच्छा विचार नहीं है।


कैसे this में केवल उल्लेखनीय अंतर जावास्क्रिप्ट "संस्करण" के बीच नियंत्रित किया जाता है strict mode, जहां यह फेंक देंगे अगर null या undefined (की स्थिति में call या apply या bind में भेजा जाता है एक त्रुटि है में है this value)। अन-सख्त मोड में, this केवल वैश्विक वस्तु के लिए मजबूर किया गया था।

"use strict"; 
foo.apply(null); // Throw error 

इस सहायता की आशा करें!

+2

आप शायद अपने वाक्यांश में अस्पष्ट हो सकते हैं, लेकिन 'foo.apply (null);' सख्त मोड में कोई त्रुटि नहीं फेंकता है। 'फंक्शन foo() {this.do कुछ(); } 'अगर कोई' यह 'नहीं है (उदाहरण के लिए यदि यह 'शून्य' या 'अपरिभाषित' है तो सख्त मोड में एक त्रुटि फेंकता है)।यही वह हो सकता है जो आप कहने के लिए चाहते थे, लेकिन आप इसे जन्म के लिए अधिक स्पष्ट रूप से लिखना चाहेंगे। –