चर === अपरिभाषित बनाम टाइपो चर === "अपरिभाषित"


300

JQuery कोर शैली दिशानिर्देश एक चर परिभाषित किया गया है कि क्या जांच करने के लिए दो अलग अलग तरीकों सुझाव देते हैं।

  • सार्वत्रिक चर: typeof variable === "undefined"
  • स्थानीय चर: variable === undefined
  • गुण: object.prop === undefined

JQuery वैश्विक चर के लिए एक दृष्टिकोण और स्थानीय और गुणों के लिए अन्य का उपयोग क्यों करता है?


मैं इस सवाल का जवाब नहीं दे सकता हूं कि JQuery दोनों दृष्टिकोणों का उपयोग क्यों करेगा, लेकिन जावास्क्रिप्ट में कुछ दिलचस्प प्रश्न हैं, जिसका अर्थ है कि ये दोनों चीजें समान रूप से भिन्न हैं। यह अधिकतर समय मायने नहीं रखता (यानी यदि आपका कोड समझदार है), लेकिन फिर भी मतभेद हैं: यहां एक राइट-अप के लिए देखें - wtfjs.com/2010/02/15/undefined-is-mutable
Spudley

2
जैसा कि @Struppi ने बताया, jQuery के सबसे बाहरी फ़ंक्शन में एक तर्क है जिसका नाम अपरिभाषित है। JQuery के भीतर, foo === undefinedवैश्विक (window.undefined) के बजाय अपरिभाषित की स्थानीय प्रतिलिपि के खिलाफ जाँच कर रहा है, जिसे शायद पागल कोड द्वारा संशोधित किया गया है। तथ्य यह है कि अपरिभाषित उत्परिवर्तित निश्चित रूप से ध्यान देने योग्य है और मुझे खुशी है कि आपने किया। (+1)
पैट्रिक मैक्लेनी

1
उस लेख की वर्तमान लिंक wtfjs.com/wtfs/2010-02-15-undefined-is-mutable
enigment

जवाबों:


366

अघोषित चर के लिए, typeof fooस्ट्रिंग शाब्दिक लौटाएगा "undefined", जबकि पहचान की जांच foo === undefinedमें त्रुटि "फू परिभाषित नहीं है" को ट्रिगर करेगी ।

स्थानीय चरों के लिए (जिसे आप जानते हैं कि कहीं घोषित किए गए हैं), ऐसी कोई त्रुटि नहीं होगी, इसलिए पहचान की जाँच।


3
@goreSplatter अब आप इसे हटा नहीं सकते। :-) यह चुनना मुश्किल था, लेकिन जिस तरह से प्रश्न को हल किया गया है, यह उत्तर एक बेहतर फिट है। जिस किसी की भी रुचि सामान्य रूप से अपरिभाषित काम करने में है (जैसा कि मैं था) अन्य उत्तरों को भी देखना चाहिए, खासकर @ टिम के।
पैट्रिक मैकलेनै

4
मैं उद्धरण चिह्नों ( typeof foo; // -> "undefined") को जोड़ने के लिए जोर दूंगा यह एक स्ट्रिंग है न कि आदिम मूल्य undefined
c24w

117

मैं typeof foo === "undefined"हर जगह का उपयोग कर रहा हूँ । वह कभी गलत नहीं हो सकता।

मैं इस कारण की कल्पना करता हूं कि jQuery दो अलग-अलग तरीकों की सिफारिश क्यों करता है कि वे undefinedउस फ़ंक्शन के भीतर अपने स्वयं के चर को परिभाषित करते हैं जो jQuery कोड में रहता है, इसलिए उस फ़ंक्शन के भीतर undefinedबाहर से छेड़छाड़ से सुरक्षित है। मैं यह भी कल्पना करूंगा कि किसी व्यक्ति ने दो अलग-अलग तरीकों से बेंचमार्क किया है और पता चला है कि foo === undefinedयह तेज है और इसलिए यह तय किया कि यह जाने का रास्ता है। [अद्यतन: जैसा कि टिप्पणियों में कहा गया है, के साथ तुलना undefinedभी थोड़ी कम है, जो एक विचार हो सकता है।] हालांकि, व्यावहारिक स्थितियों में लाभ पूरी तरह से महत्वहीन होगा: यह जांच कभी भी, कभी भी किसी भी तरह की अड़चन नहीं होगी, और क्या आपका हारना महत्वपूर्ण है: तुलना के लिए एक मेजबान वस्तु की संपत्ति का मूल्यांकन एक त्रुटि फेंक सकता है जबकि एtypeof चेक कभी नहीं होगा।

उदाहरण के लिए, XML को पार्स करने के लिए IE में निम्नलिखित का उपयोग किया जाता है:

var x = new ActiveXObject("Microsoft.XMLDOM");

यह जाँचने के लिए कि क्या इसकी कोई loadXMLविधि सुरक्षित है:

typeof x.loadXML === "undefined"; // Returns false

दूसरी ओर:

x.loadXML === undefined; // Throws an error

अपडेट करें

typeofचेक का एक और लाभ जिसका मैं उल्लेख करना भूल गया था कि यह अघोषित चर के साथ भी काम करता है, जो कि foo === undefinedचेक नहीं करता है, और वास्तव में ए फेंकता है ReferenceError। मुझे याद दिलाने के लिए @LinusKleen को धन्यवाद। उदाहरण के लिए:

typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError

निचला रेखा: हमेशा typeofचेक का उपयोग करें।


10
धन्यवाद टिम। प्रदर्शन के बारे में आपकी बात समझ में आती है। फ़ाइल आकार पर प्रभाव के बारे में jQuery की टीम अधिक चिंतित है। foo === undefined, जब कम से कम, शायद कुछ ऐसा है f===u, जबकिtypeof foo === "undefined" इसे केवल कम किया जा सकता है typeof f==="undefined"
पैट्रिक मैकेलेनै

1
आप var u = "undefined"इसे परिभाषित और कम कर सकते हैं typeof f==u, जो चीजों को बेहतर बनाता है लेकिन अभी भी बड़ा है।
टिम डाउन

5
अच्छे अंक, लेकिन मुझे यकीन नहीं है कि typeofअघोषित चर के खिलाफ सुरक्षा एक फायदा है। यदि कुछ भी यह टाइपोस को आसानी से अतीत में फिसलने देता है, और जब आप वास्तव में अघोषित चर के प्रकार की जांच करना चाहते हैं तो मैं नहीं देख सकता।
डेविड टैंग

2
@ Box9: मैं एक पुस्तकालय में इसका उपयोग करने की कल्पना दूसरे पुस्तकालय की उपस्थिति के लिए कर सकता हूं।
टिम डाउन

2
@jontro: यह JSLint का उपयोग न करने का एक कारण है।
टिम डाउन

29

टाइपोफ़-वैरिएंट का उपयोग करने का एक और कारण: undefinedइसे फिर से परिभाषित किया जा सकता है।

undefined = "foo";
var variable = "foo";
if (variable === undefined)
  console.log("eh, what?!");

का परिणाम typeof variable नहीं हो सकता।

अद्यतन : ध्यान दें कि यह ES5 में ऐसा नहीं है, वैश्विक undefinedगैर-विन्यास योग्य, गैर-लिखने योग्य संपत्ति है:

ग्लोबल ऑब्जेक्ट के 15.1.1 मूल्य गुण
[…]
15.1.1.3 अपरिभाषित
मूल्य undefinedअपरिभाषित है (8.1 देखें)। इस गुण के गुण
{[[लिखने योग्य]]: झूठे, [[असंख्य]]: झूठे, [[विन्यास योग्य]]: झूठे} हैं।

लेकिन यह अभी भी एक स्थानीय चर द्वारा छाया हो सकता है:

(function() {
  var undefined = "foo";
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})()

या पैरामीटर:

(function(undefined) {
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})("foo")

17
ES5 में पुन: परिभाषित नहीं किया जा सकता है।
Ry-

6
undefinedES5 में वैश्विक संपत्ति को फिर से परिभाषित नहीं किया जा सकता है, लेकिन फिर भी एक स्थानीय चर के साथ छाया जा सकता है। void 0छोटा और सुरक्षित है।
ओरियल सेप

7

क्योंकि undefinedहमेशा घोषित नहीं किया जाता है, लेकिन jQuery undefinedअपने मुख्य कार्य में घोषित करता है। इसलिए वे undefinedआंतरिक रूप से सुरक्षित मूल्य का उपयोग करते हैं , लेकिन बाहर, वे typeofसुरक्षित होने के लिए शैली का उपयोग करते हैं।



1

स्थानीय चर के लिए, के साथ जाँच localVar === undefined करना काम करेगा क्योंकि उन्हें स्थानीय दायरे में कहीं परिभाषित किया गया होगा या उन्हें स्थानीय नहीं माना जाएगा।

उन चरों के लिए जो स्थानीय नहीं हैं और कहीं भी परिभाषित नहीं हैं, चेक someVar === undefinedअपवाद को फेंक देगा: अनट्रीटेड संदर्भ: जे परिभाषित नहीं है

यहां कुछ कोड दिए गए हैं जो स्पष्ट करेंगे कि मैं ऊपर क्या कह रहा हूं। कृपया आगे स्पष्टता के लिए इनलाइन टिप्पणियों पर ध्यान दें

function f (x) {
    if (x === undefined) console.log('x is undefined [x === undefined].');
    else console.log('x is not undefined [x === undefined.]');

    if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
    else console.log('x is not undefined [typeof(x) === \'undefined\'].');

    // This will throw exception because what the hell is j? It is nowhere to be found.
    try
    {
        if (j === undefined) console.log('j is undefined [j === undefined].');
        else console.log('j is not undefined [j === undefined].');
    }
    catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}

    // However this will not throw exception
    if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
    else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};

अगर हम उपरोक्त कोड को इस तरह कहते हैं:

f();

आउटपुट यह होगा:

x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

अगर हम उपरोक्त कोड को इन जैसे कहते हैं (वास्तव में किसी भी मूल्य के साथ):

f(null); 
f(1);

उत्पादन होगा:

x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

जब आप इस तरह की जाँच करते हैं: typeof x === 'undefined'आप अनिवार्य रूप से यह पूछ रहे हैं: कृपया जाँच लें कि क्या xस्रोत कोड में कहीं चर मौजूद है (परिभाषित किया गया है)। (ज्यादा या कम)। यदि आप C # या Java जानते हैं, तो इस प्रकार की जाँच कभी नहीं की जाती है क्योंकि यदि यह मौजूद नहीं है, तो यह संकलन नहीं करेगा।

<== फिडल मी ==>


1

सारांश:

जब वैश्विक दायरे में हम वास्तव में सही लौटना चाहते हैं यदि चर घोषित नहीं हुआ है या उसका मूल्य नहीं है undefined:

var globalVar1;

// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);

// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);

क्योंकि वैश्विक दायरे में हम 100% निश्चित नहीं हैं यदि एक चर घोषित किया जाता है तो यह हमें एक संदर्भ दे सकता है। जब हम typeofअज्ञात चर पर ऑपरेटर का उपयोग करते हैं तो हमें यह मुद्दा तब नहीं मिलता है जब चर घोषित नहीं होता है:

var globalVar1;

console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');

यह इस तथ्य के कारण है कि typeofऑपरेटर undefinedएक स्ट्रिंग घोषित करता है जब एक चर घोषित नहीं होता है या वर्तमान में वह मूल्य रखता undefinedहै जो हम चाहते हैं।


  • स्थानीय चर के साथ हमें यह समस्या नहीं है क्योंकि हम पहले से जानते हैं कि यह चर मौजूद होगा। हम केवल संबंधित फ़ंक्शन में देख सकते हैं यदि चर मौजूद है।
  • ऑब्जेक्ट प्रॉपर्टी के साथ हमारे पास यह समस्या नहीं है क्योंकि जब हम किसी ऑब्जेक्ट प्रॉपर्टी को देखने की कोशिश करते हैं जो मौजूद नहीं है तो हमें वैल्यू भी मिलती है undefined

var obj = {};

console.log(obj.myProp === undefined);


-5

typeof a === 'undefined'a === 'undefined'नोड v6.9.1 पर लगभग 2 गुना तेजी से होता है।


3
वे वही चीजें नहीं हैं जो आपने टाइप की थीं। मुझे लगता है कि आप undefinedदूसरे भाग में थे, नहीं'undefined'
डरावना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.