मैंने इस विशेष व्यवहार को समझने के लिए गहराई से खुदाई की और मुझे लगता है कि मुझे एक अच्छा स्पष्टीकरण मिल गया है।
इससे पहले कि मैं आपको उर्फ क्यों नहीं कर पा document.getElementByIdरहा हूं, मैं यह समझाने की कोशिश करूंगा कि जावास्क्रिप्ट कैसे काम करती है / वस्तुएं काम करती हैं।
जब भी आप एक जावास्क्रिप्ट फ़ंक्शन शुरू करते हैं, तो जावास्क्रिप्ट दुभाषिया एक दायरा निर्धारित करता है और इसे फ़ंक्शन में पास करता है।
निम्नलिखित कार्य पर विचार करें:
function sum(a, b)
{
return a + b;
}
sum(10, 20);
यह फ़ंक्शन विंडो स्कोप में घोषित किया गया है और जब आप इसे आमंत्रित करते हैं thisतो सम फ़ंक्शन के अंदर का मान वैश्विक Windowऑब्जेक्ट होगा।
'योग' फ़ंक्शन के लिए, यह कोई फर्क नहीं पड़ता कि 'यह' का मान क्या है क्योंकि यह इसका उपयोग नहीं कर रहा है।
निम्नलिखित कार्य पर विचार करें:
function Person(birthDate)
{
this.birthDate = birthDate;
this.getAge = function() { return new Date().getFullYear() - this.birthDate.getFullYear(); };
}
var dave = new Person(new Date(1909, 1, 1));
dave.getAge();
जब आप dave.getAge फ़ंक्शन को कॉल करते हैं, तो जावास्क्रिप्ट दुभाषिया देखता है कि आप daveऑब्जेक्ट पर getAge फ़ंक्शन को कॉल कर रहे हैं , इसलिए यह फ़ंक्शन thisको सेट daveऔर कॉल करता getAgeहै। getAge()सही ढंग से वापस आ जाएगी 100।
आप जान सकते हैं कि जावास्क्रिप्ट में आप applyविधि का उपयोग करके गुंजाइश निर्दिष्ट कर सकते हैं । चलो कोशिश करते हैं कि।
var dave = new Person(new Date(1909, 1, 1));
var bob = new Person(new Date(1809, 1, 1));
dave.getAge.apply(bob);
उपर्युक्त पंक्ति में, जावास्क्रिप्ट को दायरा तय करने देने के बजाय, आप bobऑब्जेक्ट के रूप में स्वयं स्कोप पास कर रहे हैं । भले ही आप ऑब्जेक्ट पर 'विचार' करते getAgeहैं, फिर 200भी वापस आ जाएंगे ।getAgedave
उपरोक्त सभी का क्या मतलब है? कार्य आपके जावास्क्रिप्ट ऑब्जेक्ट्स के साथ 'शिथिल' हैं। जैसे आप कर सकते हैं
var dave = new Person(new Date(1909, 1, 1));
var bob = new Person(new Date(1809, 1, 1));
bob.getAge = function() { return -1; };
bob.getAge();
dave.getAge();
चलिए अगला कदम उठाते हैं।
var dave = new Person(new Date(1909, 1, 1));
var ageMethod = dave.getAge;
dave.getAge();
ageMethod();
ageMethodनिष्पादन एक त्रुटि फेंकता है! क्या हुआ?
यदि आप मेरे उपरोक्त बिंदुओं को ध्यान से पढ़ते हैं, तो आप ध्यान देंगे कि इस dave.getAgeपद्धति daveको thisऑब्जेक्ट के रूप में बुलाया गया था जबकि जावास्क्रिप्ट ageMethodनिष्पादन के लिए 'गुंजाइश' निर्धारित नहीं कर सकता था। इसलिए इसने वैश्विक 'विंडो' को 'इस' के रूप में पारित किया। अब चूंकि संपत्ति windowनहीं है birthDate, तो ageMethodनिष्पादन विफल हो जाएगा।
इसे कैसे ठीक करें? सरल,
ageMethod.apply(dave);
क्या उपरोक्त सभी समझ में आया? यदि ऐसा होता है, तो आप यह समझाने में सक्षम होंगे कि आप उपनाम क्यों नहीं दे पा रहे हैं document.getElementById:
var $ = document.getElementById;
$('someElement');
$के रूप में बुलाया windowजाता है thisऔर यदि getElementByIdकार्यान्वयन होने की उम्मीद thisहै document, तो यह विफल हो जाएगा।
इसे ठीक करने के लिए, आप कर सकते हैं
$.apply(document, ['someElement']);
तो यह Internet Explorer में काम क्यों करता है?
मुझे getElementByIdIE में आंतरिक कार्यान्वयन का पता नहीं है , लेकिन jQuery स्रोत ( inArrayविधि कार्यान्वयन) में एक टिप्पणी कहती है कि IE में window == document,। अगर ऐसा है, तो एलियासिंग document.getElementByIdको IE में काम करना चाहिए।
इसे और स्पष्ट करने के लिए, मैंने एक विस्तृत उदाहरण बनाया है। Personनीचे दिए गए फ़ंक्शन पर एक नज़र डालें।
function Person(birthDate)
{
var self = this;
this.birthDate = birthDate;
this.getAge = function()
{
if(this.constructor == Person)
return new Date().getFullYear() - this.birthDate.getFullYear();
else
return -1;
};
this.getAgeSmarter = function()
{
return self.getAge();
};
this.getAgeSmartest = function()
{
var scope = this.constructor == Person ? this : self;
return scope.getAge();
};
}
Personउपरोक्त फ़ंक्शन के लिए , यहां विभिन्न getAgeविधियों का व्यवहार कैसे किया जाएगा।
Personफ़ंक्शन का उपयोग करके दो ऑब्जेक्ट बनाएं ।
var yogi = new Person(new Date(1909, 1,1));
var anotherYogi = new Person(new Date(1809, 1, 1));
console.log(yogi.getAge());
सीधे आगे, getAge पद्धति को yogiवस्तु thisऔर आउटपुट के रूप में वस्तु मिलती है 100।
var ageAlias = yogi.getAge;
console.log(ageAlias());
जावास्क्रिप्ट इंटरप्रिटर windowऑब्जेक्ट को सेट करता है thisऔर हमारी getAgeविधि वापस आ जाएगी -1।
console.log(ageAlias.apply(yogi));
यदि हम सही गुंजाइश निर्धारित करते हैं, तो आप ageAliasविधि का उपयोग कर सकते हैं ।
console.log(ageAlias.apply(anotherYogi));
यदि हम किसी अन्य व्यक्ति वस्तु में गुजरते हैं, तो यह अभी भी उम्र की सही गणना करेगा।
var ageSmarterAlias = yogi.getAgeSmarter;
console.log(ageSmarterAlias());
ageSmarterसमारोह मूल पर कब्जा कर लिया thisवस्तु तो अब आप सही गुंजाइश की आपूर्ति के बारे में चिंता की जरूरत नहीं है।
console.log(ageSmarterAlias.apply(anotherYogi));
इसके साथ समस्या ageSmarterयह है कि आप कभी भी किसी अन्य वस्तु के लिए गुंजाइश निर्धारित नहीं कर सकते हैं।
var ageSmartestAlias = yogi.getAgeSmartest;
console.log(ageSmartestAlias());
console.log(ageSmartestAlias.apply(document));
ageSmartestसमारोह मूल गुंजाइश है, तो गलत गुंजाइश आपूर्ति की है का उपयोग करेगा।
console.log(ageSmartestAlias.apply(anotherYogi));
आप अभी भी किसी अन्य Personऑब्जेक्ट को पास करने में सक्षम होंगे getAgeSmartest। :)