मैंने इस विशेष व्यवहार को समझने के लिए गहराई से खुदाई की और मुझे लगता है कि मुझे एक अच्छा स्पष्टीकरण मिल गया है।
इससे पहले कि मैं आपको उर्फ क्यों नहीं कर पा 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
भी वापस आ जाएंगे ।getAge
dave
उपरोक्त सभी का क्या मतलब है? कार्य आपके जावास्क्रिप्ट ऑब्जेक्ट्स के साथ 'शिथिल' हैं। जैसे आप कर सकते हैं
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 में काम क्यों करता है?
मुझे getElementById
IE में आंतरिक कार्यान्वयन का पता नहीं है , लेकिन 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
। :)