javascript - जावास्क्रिप्ट में उदाहरण ऑपरेटर क्या है?




operators instanceof (6)

जावास्क्रिप्ट में कीवर्ड का instanceof काफी उलझन में हो सकता है जब पहली बार इसका सामना करना पड़ता है, क्योंकि लोग सोचते हैं कि जावास्क्रिप्ट एक ऑब्जेक्ट उन्मुख प्रोग्रामिंग भाषा नहीं है।

  • यह क्या है?
  • यह किस समस्या का समाधान करता है?
  • यह कब उचित है और कब नहीं?

का उदाहरण

बाएं हाथ की ओर (एलएचएस) ऑपरेंड वास्तविक वस्तु है जो राइट हैंड साइड (आरएचएस) ऑपरेंड को परीक्षण किया जा रहा है जो कि कक्षा का वास्तविक निर्माता है। मूल परिभाषा है:

Checks the current object and returns true if the object
is of the specified object type.

यहां कुछ अच्छे उदाहरण दिए गए हैं और यहां मोज़िला की डेवलपर साइट से सीधे एक उदाहरण लिया गया है:

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

उल्लेख करने योग्य एक बात यह है कि यदि वस्तु क्लैस के प्रोटोटाइप से प्राप्त होती है तो instanceof सही साबित होता है:

var p = new Person("Jon");
p instanceof Person

यह p instanceof Person p से Person.prototype है क्योंकि pPerson.prototype से विरासत में है।

ओपी के अनुरोध के अनुसार

मैंने कुछ नमूना कोड और एक स्पष्टीकरण के साथ एक छोटा सा उदाहरण जोड़ा है।

जब आप एक चर घोषित करते हैं तो आप इसे एक विशिष्ट प्रकार देते हैं।

उदाहरण के लिए:

int i;
float f;
Customer c;

उपर्युक्त आपको कुछ चर दिखाता है, अर्थात् i , f , और c । प्रकार integer , float और उपयोगकर्ता परिभाषित Customer डेटा प्रकार हैं। उपरोक्त प्रकार के प्रकार किसी भी भाषा के लिए नहीं हो सकते हैं, सिर्फ जावास्क्रिप्ट। हालांकि, जावास्क्रिप्ट के साथ जब आप एक वेरिएबल घोषित करते हैं तो आप स्पष्ट रूप से किसी प्रकार को परिभाषित नहीं करते हैं, var x , x एक संख्या / स्ट्रिंग / उपयोगकर्ता परिभाषित डेटा प्रकार हो सकता है। तो क्या instanceof यह है कि यह ऑब्जेक्ट को यह देखने के लिए जांचता है कि यह निर्दिष्ट प्रकार का है या नहीं, ताकि Customer ऑब्जेक्ट को ऊपर ले जाया जा सके:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

ऊपर हमने देखा है कि c प्रकार के Customer साथ घोषित किया गया था। हमने इसे नया किया है और जांच की है कि यह Customer प्रकार का है या नहीं। निश्चित रूप से, यह सच हो जाता है। फिर भी Customer ऑब्जेक्ट का उपयोग करके हम जांचते हैं कि यह String । नहीं, निश्चित रूप से एक String नहीं है जिसे हमने Customer ऑब्जेक्ट को नया किया है, String ऑब्जेक्ट नहीं। इस मामले में, यह झूठी वापसी करता है।

वास्तव में यह उतना आसान है!


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

उदाहरण के लिए, चलिए एक प्रकार और उप प्रकार परिभाषित करते हैं:

function Foo(){ //a Foo constructor
    //assign some props
    return this;
}

function SubFoo(){ //a SubFoo constructor
    Foo.call( this ); //inherit static props
    //assign some new props
    return this;
}

SubFoo.prototype = new Foo(); // Inherit prototype

अब हमारे पास कुछ "कक्षाएं" हैं, कुछ उदाहरण बनाने दें, और पता लगाएं कि वे किस प्रकार के उदाहरण हैं:

var 
    foo = new Foo()
,   subfoo = new SubFoo()
;

alert( 
    "Q: Is foo an instance of Foo? "
+   "A: " + ( foo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is foo an instance of SubFoo? " 
+   "A: " + ( foo instanceof SubFoo ) 
); // -> false

alert( 
    "Q: Is subfoo an instance of Foo? "
+   "A: " + ( subfoo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of SubFoo? "
+   "A: " + ( subfoo instanceof SubFoo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of Object? "
+   "A: " + ( subfoo instanceof Object ) 
); // -> true

आखिरी पंक्ति देखें? फ़ंक्शन में सभी "नई" कॉल ऑब्जेक्ट से प्राप्त होने वाली ऑब्जेक्ट को वापस लौटाती हैं। वस्तु निर्माण शॉर्टेंड का उपयोग करते समय भी यह सच है:

alert( 
    "Q: Is {} an instance of Object? "
+   "A: " + ( {} instanceof Object ) 
); // -> true

और "कक्षा" परिभाषाओं के बारे में क्या? वे क्या उदाहरण हैं?

alert( 
    "Q: Is Foo an instance of Object? "
+   "A:" + ( Foo instanceof Object) 
); // -> true

alert( 
    "Q: Is Foo an instance of Function? "
+   "A:" + ( Foo instanceof Function) 
); // -> true

मुझे लगता है कि यह समझना कि किसी भी वस्तु बहु प्रकार के उदाहरण हो सकती है, क्योंकि आप (गलत तरीके से) मानते हैं कि आप instanceof उपयोग के माध्यम से कह सकते हैं, कह सकते हैं और ऑब्जेक्ट और फ़ंक्शन को अलग कर सकते हैं। चूंकि यह अंतिम उदाहरण स्पष्ट रूप से दिखाता है कि एक कार्य एक वस्तु है।

यह भी महत्वपूर्ण है यदि आप किसी भी विरासत पैटर्न का उपयोग कर रहे हैं और किसी ऑब्जेक्ट के संतान को बतख-टाइपिंग के अलावा अन्य तरीकों से पुष्टि करना चाहते हैं।

उम्मीद है कि किसी को instanceof खोज में मदद करता है।


प्रश्न पर "यह कब उचित है और कब नहीं?", मेरे 2 सेंट:

instanceof उत्पादन कोड में शायद ही कभी उपयोगी होता है, लेकिन परीक्षणों में उपयोगी जहां आप यह कहना चाहते हैं कि आपका कोड सही प्रकार की वस्तुओं को वापस / बनाता है। आपके कोड लौटने / बनाने के ऑब्जेक्ट्स के प्रकार के बारे में स्पष्ट होने के कारण, आपके परीक्षण को समझने और दस्तावेज करने के लिए आपके परीक्षण अधिक शक्तिशाली हो जाते हैं।


मुझे बस एक असली दुनिया का आवेदन मिला और अब मुझे लगता है कि अब इसका इस्तेमाल करेंगे।

यदि आप jQuery ईवेंट का उपयोग करते हैं, तो कभी-कभी आप एक अधिक सामान्य फ़ंक्शन लिखना चाहते हैं जिसे सीधे (ईवेंट के बिना) भी कहा जा सकता है। आप यह जांचने के लिए instanceof का उपयोग कर सकते हैं कि आपके फ़ंक्शन का पहला पैरामीटर jQuery.Event उदाहरण है और उचित प्रतिक्रिया दें।

var myFunction = function (el) {                
    if (el instanceof $.Event) 
        // event specific code
    else
        // generic code
};

$('button').click(recalc);    // Will execute event specific code
recalc('myParameter');  // Will execute generic code

मेरे मामले में, फ़ंक्शन को सभी के लिए कुछ (किसी बटन पर क्लिक ईवेंट के माध्यम से) या केवल एक विशिष्ट तत्व की गणना करने की आवश्यकता होती है। मैंने जो कोड इस्तेमाल किया था:

var recalc = function (el) { 
    el = (el == undefined || el instanceof $.Event) ? $('span.allItems') : $(el);
    // calculate...
};

यहां अन्य उत्तर सही हैं, लेकिन वे इस बात में नहीं आते कि वास्तव में कैसे काम करता है, जो कि कुछ भाषा वकीलों के लिए ब्याज हो सकता है।

जावास्क्रिप्ट में प्रत्येक ऑब्जेक्ट में प्रोटोटाइप होता है, जो __proto__ प्रॉपर्टी के माध्यम से सुलभ __proto__ है। कार्यों में prototype प्रॉपर्टी भी होती है, जो उनके द्वारा बनाई गई किसी ऑब्जेक्ट के लिए प्रारंभिक __proto__ है। जब कोई फ़ंक्शन बनाया जाता है, तो इसे prototype लिए एक अद्वितीय वस्तु दी जाती है। instanceof ऑपरेटर आपको जवाब देने के लिए इस विशिष्टता का उपयोग करता है। यहां बताया गया है कि यदि आप इसे फ़ंक्शन के रूप में लिखते हैं तो यह instanceof कैसा दिख सकता है।

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

यह मूल रूप से ईसीएमए -262 संस्करण 5.1 (ईएस 5 के रूप में भी जाना जाता है), खंड 15.3.5.3 है।

ध्यान दें कि आप किसी ऑब्जेक्ट को किसी फ़ंक्शन की prototype प्रॉपर्टी पर पुन: असाइन कर सकते हैं, और इसके निर्माण के बाद आप किसी ऑब्जेक्ट की __proto__ प्रॉपर्टी को पुन: असाइन कर सकते हैं। यह आपको कुछ दिलचस्प परिणाम देगा:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

instanceof लिए सिर्फ वाक्य रचनात्मक चीनी isPrototypeOf :

function Ctor() {}
var o = new Ctor();

o instanceof Ctor; // true
Ctor.prototype.isPrototypeOf(o); // true

o instanceof Ctor === Ctor.prototype.isPrototypeOf(o); // equivalent

instanceof सिर्फ एक वस्तु के एक निर्माता के प्रोटोटाइप पर निर्भर करता है।

एक कन्स्ट्रक्टर सिर्फ एक सामान्य कार्य है। कड़ाई से बोलना यह एक कार्य वस्तु है, क्योंकि सब कुछ जावास्क्रिप्ट में एक वस्तु है। और इस फ़ंक्शन ऑब्जेक्ट में प्रोटोटाइप होता है, क्योंकि प्रत्येक फ़ंक्शन में प्रोटोटाइप होता है।

एक प्रोटोटाइप सिर्फ एक सामान्य वस्तु है, जो किसी अन्य वस्तु की प्रोटोटाइप श्रृंखला के भीतर स्थित है। इसका मतलब है कि किसी अन्य ऑब्जेक्ट की प्रोटोटाइप श्रृंखला में होने से प्रोटोटाइप पर ऑब्जेक्ट होता है:

function f() {} //  ordinary function
var o = {}, // ordinary object
 p;

f.prototype = o; // oops, o is a prototype now
p = new f(); // oops, f is a constructor now

o.isPrototypeOf(p); // true
p instanceof f; // true

instanceof ऑपरेटर से बचा जाना चाहिए क्योंकि यह कक्षाएं बनाता है, जो जावास्क्रिप्ट में मौजूद नहीं है। class कीवर्ड के बावजूद ES2015 में नहीं, क्योंकि class फिर से सिर्फ वाक्य रचनात्मक चीनी है ... लेकिन यह एक और कहानी है।





instanceof