2012-01-30 22 views
7

सिर्फ बौद्धिक जिज्ञासा से बाहर, क्यों जावास्क्रिप्टजावास्क्रिप्ट: z = z || [] VAR का उपयोग नहीं करते समय एक त्रुटि फेंकता है - क्यों?

var z = z || []; 

z प्रारंभ करने में (के रूप में जेड शुरू में परिभाषित कर सकते हैं)

लेकिन वर के बिना, यह एक त्रुटि फेंकता है (वैश्विक अंतरिक्ष में)

z = z || []; 
को स्वीकार करता है

(यदि ज़ेड पहले अनिर्धारित है)

वैश्विक स्थान में आपको VAR का उपयोग करने की आवश्यकता नहीं है हालांकि मुझे यह मिल सकता है ई बुरा अभ्यास।

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

What is the purpose of the var keyword and when to use it (or omit it)?

नोट घोषणा कि सवाल का डुप्लिकेट है "आप वैश्विक क्षेत्र में हैं, तो फिर वहाँ कोई अंतर नहीं है।"

स्पष्ट रूप से यह मेरे कामकाजी उदाहरण के मुताबिक 100% सच नहीं है।

यह एक मोड़ है या वैध तर्क है?


के रूप में मैं यह सीखा है जवाब का एक सारांश जोड़ने:

टिम (नीचे देखें) मेरी गलतफहमी की कुंजी के लिए धन्यवाद साकार नहीं कर रहा था इस (जावास्क्रिप्ट के मौलिक)

var z; अगर z पहले से मौजूद है

कि कैसे इस अभिव्यक्ति यह दोनों तरीके हैं लगता है, यदि आप गलत मानते हैं कि "var Z" हमेशा initializes बिल्कुल कुछ नहीं करता है।

बाएं से शुरू, "var Z" बस यकीन है कि जेड परिभाषित किया गया है लेकिन अगर यह पहले से मौजूद है वास्तव में किसी भी मौजूदा मूल्य को प्रभावित नहीं करता बनाता है। फिर सही पर, अगर z पहले से मौजूद है, यह प्रयोग किया जाता है, अगर नहीं, चर सिर्फ घोषित किया गया था (लेकिन खाली) तो यह उपयोग नहीं किया जाएगा लेकिन एक त्रुटि फेंक नहीं होंगे।

यह देखते हुए और जावास्क्रिप्ट में इस मुद्दे को उत्थापन के इस प्रकार पर एक उत्कृष्ट लेख है: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

बहुत धन्यवाद minitech और करने के लिए हर किसी की भी जो योगदान दिया!

+2

एक सामान्य नियम के रूप में: वास्तविक त्रुटि संदेश की प्रतिलिपि बनाना आमतौर पर "त्रुटि फेंकता" लिखने से अधिक सहायक होता है। –

उत्तर

6

z = z || [] किसी भी क्षेत्र (वैश्विक या नहीं) में फेंक देगा जहां स्कोप श्रृंखला में z नहीं है। इसका कारण यह है कि अभिव्यक्ति पहले किसी मौजूदा चर के मान को पुनर्प्राप्त करने का प्रयास करती है जिसे दाएं हाथ पर z कहा जाता है, जो कोई त्रुटि नहीं होने पर त्रुटि होती है।

कारण है कि var z = z || [] एक त्रुटि फेंक नहीं है इससे पहले कि अभिव्यक्ति निष्पादित किया जाता है, एक प्रभाव सामान्यतः उत्थापन रूप में जाना जाता है (अगर यह पहले से ही मौजूद नहीं है) कि चर z बनाया जाता है।

दूसरी तरफ, एक अनसुलझा पहचानकर्ता (उदा। z = 2) के लिए मान निर्दिष्ट करना किसी भी दायरे में त्रुटि के बिना काम करेगा (ईसीएमएस्क्रिप्ट 5 सख्त मोड को छोड़कर, जो इसे रोकता है और फेंकता है)। यदि पहचानकर्ता को हल नहीं किया जा सकता है, तो इसे स्कोप श्रृंखला में अंतिम वस्तु की संपत्ति के रूप में जोड़ा जाएगा, जो वैश्विक वस्तु है, इसलिए वैश्विक चर बनाने की उपस्थिति दे रही है।

+0

आह मुझे लगता है कि मुझे यह मिल गया। तो "var z" बाईं ओर पहली बार किया जाता है, जैसे कि "एक नया ज़ेड बनाएं" को निर्देशित करना, लेकिन फिर यह दाईं तरफ एक "पुराना ज़ेड" ढूंढता है। उस क्रम में, "z" को बाईं ओर अभी शुरू किया गया है, इसलिए दाईं तरफ "z" अपरिभाषित नहीं है, हालांकि यह खाली है। Var के बिना, दाईं ओर "z" बस खाली नहीं है, यह अपरिभाषित है। हम्म ठीक है - अगर "var z" इसे बाईं ओर नया रूप में परिभाषित करता है, तो यह कोड तब मौजूदा मानों को कैसे सुरक्षित रखता है? ऐसा लगता है कि यह दोनों तरीकों से है, दाईं तरफ बाईं ओर शुरू होता है, लेकिन दाईं ओर मूल्य भी रख सकता है। –

+0

@ck_: हाँ, मुझे लगता है कि आपको यह मिल गया है, हालांकि शब्दावली को कुछ देखभाल की आवश्यकता है क्योंकि 'अपरिभाषित' जावास्क्रिप्ट में एक वास्तविक मूल्य है और वास्तव में एक चर को निर्दिष्ट डिफ़ॉल्ट मान है (उदाहरण के लिए, 'var x; ' 'अपरिभाषित' के प्रारंभिक मान के साथ 'x' नामक एक चर बनाता है, जो एक अस्तित्वहीन 'x' से अलग है जिसे कभी घोषित नहीं किया गया है)। मैं "अविकसित" या "अस्तित्वहीन" के लिए जाऊंगा। –

+0

@ck_: मौजूदा मानों को संरक्षित करने के संबंध में, 'var z;' पूरी तरह से कुछ भी नहीं करता है यदि 'z' पहले से मौजूद है, जो भी उसका मान है। –

10

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

यदि आप वैश्विक दायरे में हैं, तो आप एक गैर-परिवर्तनीय चर को असाइन कर सकते हैं और यह वही प्रभाव होगा जैसा कि यह घोषित किया जा सकता है। बेशक, आपके मामले में, यह अपरिभाषित है।यह कहा जा रहा है, हालांकि यह बौद्धिक जिज्ञासा से बाहर हो सकता है, आप कभी नहीं

var z = z || []; 

बारे में है, क्योंकि यह कोई मतलब नहीं है ऐसा करने के लिए होगा। बल्कि, आप कर सकते हैं:

if(!window.z) { 
    window.z = []; 
} 

। असल में, जब मैं वैश्विक दायरे में चीजें घोषित करता हूं (जो कभी भी ;) नहीं है) तो मैं इसके बजाय window.something का उपयोग करता हूं क्योंकि यह मेरा इरादा अधिक स्पष्ट करता है।

+0

** जब आप इसे घोषित नहीं करते हैं, तो आपकी स्क्रिप्ट एक अपरिभाषित चर का उपयोग करने का प्रयास करती है ** - प्रतीक्षा करें कि आप z = z एक्सेस z कह रहे हैं लेकिन var z = z नहीं है? दूसरा ज़ेड अभी भी वैश्विक दायरे में है क्योंकि यह पहला है अगर यह किसी फ़ंक्शन के बाहर है। (परेशान) –

+1

@ck_: अंतर यह है कि 'var' का उपयोग करके किसी भी कथन को निष्पादित करने से पहले 'z' चर बनाया जा सकता है। –

4

आप एक अविकसित चर z = 123 असाइन कर सकते हैं; हालांकि आप z = z || [] करता है जो एक को पढ़ने का प्रयास नहीं कर सकता है।