मैं इस विशेष व्यवहार को समझने के गहरे खोदा और मुझे लगता है कि मैं एक अच्छा स्पष्टीकरण मिल गया है।
इससे पहले कि मैं document.getElementById
को उपनाम करने में सक्षम न हो, मैं यह बताने की कोशिश करूंगा कि जावास्क्रिप्ट फ़ंक्शन/ऑब्जेक्ट्स कैसे काम करते हैं।
जब भी आप जावास्क्रिप्ट फ़ंक्शन का आह्वान करते हैं, तो जावास्क्रिप्ट दुभाषिया एक दायरा निर्धारित करता है और इसे फ़ंक्शन में पास करता है।
समारोह निम्नलिखित पर विचार करें:
function sum(a, b)
{
return a + b;
}
sum(10, 20); // returns 30;
इस समारोह विंडो दायरे में घोषित किया जाता है और जब आप इसे योग समारोह के अंदर 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(); //returns 100.
जब आप dave.getAge फ़ंक्शन को कॉल करें, जावास्क्रिप्ट दुभाषिया देखता है कि आप, dave
वस्तु पर getAge समारोह बुला रहे हैं तो यह this
को dave
सेट करता है और कहता है:
समारोह निम्नलिखित पर विचार करें getAge
फ़ंक्शन। getAge()
सही ढंग से 100
लौटाएगा।
तुम्हें पता लग सकता है कि जावास्क्रिप्ट में आप apply
पद्धति का उपयोग करके गुंजाइश निर्दिष्ट कर सकते हैं। आइए कोशिश करें।
var dave = new Person(new Date(1909, 1, 1)); //Age 100 in 2009
var bob = new Person(new Date(1809, 1, 1)); //Age 200 in 2009
dave.getAge.apply(bob); //returns 200.
ऊपर लाइन में, बजाय दे जावास्क्रिप्ट गुंजाइश तय की है, तो आप गुंजाइश मैन्युअल 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(); //returns -1
dave.getAge(); //returns 100
का अगला कदम लेते हैं कर सकते हैं।
var dave = new Person(new Date(1909, 1, 1));
var ageMethod = dave.getAge;
dave.getAge(); //returns 100;
ageMethod(); //returns ?????
ageMethod
निष्पादन एक त्रुटि फेंकता है! क्या हुआ?
तुम मेरे ऊपर अंक को ध्यान से पढ़ें, तो आप ध्यान दें होता है कि dave.getAge
विधि dave
this
के रूप में वस्तु के साथ बुलाया गया था जबकि जावास्क्रिप्ट ageMethod
निष्पादन के लिए 'विषय-क्षेत्र' निर्धारित नहीं कर सका। तो यह वैश्विक 'विंडो' को 'इस' के रूप में पारित कर दिया। अब window
में birthDate
संपत्ति नहीं है, ageMethod
निष्पादन विफल हो जाएगा।
इसे कैसे ठीक करें? सरल,
ageMethod.apply(dave); //returns 100.
ऊपर मेकअप भावना के सभी था? यदि ऐसा है, तो आप क्यों तुम उर्फ document.getElementById
में सक्षम नहीं हैं व्याख्या करने में सक्षम हो जाएगा:
var $ = document.getElementById;
$('someElement');
$
window
this
के रूप में के साथ कहा जाता है और अगर getElementById
कार्यान्वयन this
उम्मीद कर रही है document
हो सकता है, यह असफल हो जायेगी।
फिर इसे ठीक करने के लिए, आप कर सकते हैं
$.apply(document, ['someElement']);
तो क्यों यह इंटरनेट एक्सप्लोरर में काम करता है?
मुझे आईई में getElementById
के आंतरिक कार्यान्वयन को नहीं पता है, लेकिन jQuery स्रोत (inArray
विधि कार्यान्वयन) में एक टिप्पणी का कहना है कि आईई, window == document
में।यदि ऐसा है, तो document.getElementById
को अलियासिंग करना IE में काम करना चाहिए।
इसे आगे बढ़ाने के लिए, मैंने एक विस्तृत उदाहरण बनाया है। नीचे Person
फ़ंक्शन पर एक नज़र डालें।
function Person(birthDate)
{
var self = this;
this.birthDate = birthDate;
this.getAge = function()
{
//Let's make sure that getAge method was invoked
//with an object which was constructed from our Person function.
if(this.constructor == Person)
return new Date().getFullYear() - this.birthDate.getFullYear();
else
return -1;
};
//Smarter version of getAge function, it will always refer to the object
//it was created with.
this.getAgeSmarter = function()
{
return self.getAge();
};
//Smartest version of getAge function.
//It will try to use the most appropriate scope.
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)); //Age is 100
var anotherYogi = new Person(new Date(1809, 1, 1)); //Age is 200
console.log(yogi.getAge()); //Output: 100.
सीधे आगे, getAge विधि this
और आउटपुट 100
रूप yogi
वस्तु हो जाता है।
var ageAlias = yogi.getAge;
console.log(ageAlias()); //Output: -1
जावास्क्रिप्ट interepreter this
रूप window
वस्तु सेट करता है और हमारे getAge
विधि -1
वापस आ जाएगी।
console.log(ageAlias.apply(yogi)); //Output: 100
अगर हम सही गुंजाइश निर्धारित करते हैं, आप ageAlias
विधि का उपयोग कर सकते हैं।
console.log(ageAlias.apply(anotherYogi)); //Output: 200
अगर हम किसी अन्य व्यक्ति वस्तु में पारित, यह अभी भी उम्र सही ढंग से की गणना करेगा।
var ageSmarterAlias = yogi.getAgeSmarter;
console.log(ageSmarterAlias()); //Output: 100
ageSmarter
समारोह मूल this
वस्तु पर कब्जा कर लिया अब तो आप सही गुंजाइश की आपूर्ति के बारे में चिंता करने की जरूरत नहीं है।
console.log(ageSmarterAlias.apply(anotherYogi)); //Output: 100 !!!
ageSmarter
के साथ समस्या यह है कि आप किसी अन्य वस्तु के लिए गुंजाइश सेट नहीं कर सकता है।
var ageSmartestAlias = yogi.getAgeSmartest;
console.log(ageSmartestAlias()); //Output: 100
console.log(ageSmartestAlias.apply(document)); //Output: 100
ageSmartest
समारोह मूल गुंजाइश है, तो गलत गुंजाइश आपूर्ति की है का उपयोग करेगा।
console.log(ageSmartestAlias.apply(anotherYogi)); //Output: 200
तुम अब भी getAgeSmartest
के लिए एक और Person
वस्तु पारित करने के लिए सक्षम हो जाएगा। :)
IE8 में - यह जादू समारोह या कुछ और किसी तरह का हो सकता है। –
मैंने http://stackoverflow.com/questions/954417 पर गलत उत्तरों पर टिप्पणियां जोड़ दी हैं और उन्हें यहां निर्देशित किया है। –
फ़ंक्शन.प्रोटोटाइप.बिंड विधि का समर्थन करने वाले ब्राउज़र के लिए: window.myAlias = document.getElementById.bind (दस्तावेज़); एमडीएन दस्तावेज़ खोजें, एक बाध्य शिम होगा। –