2011-05-11 14 views
12

एमडीसी में बहुत सारे कोड स्निपेट हैं जो ब्राउज़र में नए ईसीएमएस्क्रिप्ट मानकों के समर्थन को लागू करने के लिए हैं जो उनका समर्थन नहीं करते हैं, जैसे Array.prototype.map फ़ंक्शन:एमडीसी प्रोटोटाइप फ़ंक्शंस इस तरह से क्यों लिखे गए हैं?

if (!Array.prototype.map) 
{ 
    Array.prototype.map = function(fun /*, thisp */) 
    { 
    "use strict"; 

    if (this === void 0 || this === null) 
     throw new TypeError(); 

    var t = Object(this); 
    var len = t.length >>> 0; 
    if (typeof fun !== "function") 
     throw new TypeError(); 

    var res = new Array(len); 
    var thisp = arguments[1]; 
    for (var i = 0; i < len; i++) 
    { 
     if (i in t) 
     res[i] = fun.call(thisp, t[i], i, t); 
    } 

    return res; 
    }; 
} 

उपयोग करने का लाभ क्या है (यदि कोई है) यह कार्य

function(fun, thisp) 
{ 
    // same code, just without the "var thisp = arguments[1];" line: 
    "use strict"; 

    if (this === void 0 || this === null) 
    throw new TypeError(); 

    var t = Object(this); 
    var len = t.length >>> 0; 
    if (typeof fun !== "function") 
    throw new TypeError(); 

    var res = new Array(len); 
    for (var i = 0; i < len; i++) 
    { 
    if (i in t) 
     res[i] = fun.call(thisp, t[i], i, t); 
    } 

    return res; 
} 

, var t = Object(this); के बजाय var t = this; और var len = t.length >>> 0;var len = t.length; की बजाय var len = t.length >>> 0; के बजाय है?

उत्तर

7
var len = t.length >>> 0;  

यह बहुत अच्छी तरह से this question में कवर किया गया था मूल रूप से यह सुनिश्चित करें कि नंबर एक गैर नकारात्मक 32 बिट पूर्णांक है बनाता है।

वस्तु निर्माता के लिए के रूप में:

var t = Object(this); 

तो इस अशक्त या अपरिभाषित है, यह एक खाली वस्तु लौट जाएँगे। MDC Docs on Object

से वस्तु निर्माता दिए गए मूल्य के लिए एक वस्तु आवरण बनाता है। यदि मान शून्य या अपरिभाषित है, तो यह एक खाली ऑब्जेक्ट बना देगा और वापस करेगा, अन्यथा, यह प्रकार की ऑब्जेक्ट लौटाएगा जो दिए गए मान से मेल खाता है।

वे दोनों त्रुटि सुधार करने के लिए त्वरित तरीके हैं।

संपादित करें: मैं इस भाग के बारे में बहुत कठिन सोच रहा था। मैं मान रहा था कि तर्क सरणी का उपयोग करना यह सुनिश्चित करने का एक तरीका था कि तर्क अपरिभाषित करने के लिए डिफ़ॉल्ट थे, लेकिन वे वैसे भी ऐसा करते हैं। माइक होफर ने टिप्पणियों में यह सही पाया। वैकल्पिक पैरामीटर इंगित करने के लिए यह मोज़िला की कोडिंग शैली है। Function.call वैश्विक पर डिफ़ॉल्ट अगर शून्य या अपरिभाषित पहले तर्क के रूप में पारित किया जाता है। MDC Docs on Function.call

thisArg से: मज़ा अंदर इस का मूल्य निर्धारित करता है। यदि यह आर्ग शून्य या अपरिभाषित है, यह वैश्विक वस्तु होगी। अन्यथा, इस वस्तु (thisArg) के बराबर हो जाएगा (है thisArg जो अगर thisArg अगर thisArg इसी प्रकार की एक आदिम मूल्य है पहले से ही एक वस्तु, या एक स्ट्रिंग, बूलियन, या संख्या है)। इसलिए, यह हमेशा सत्य है कि टाइप == फ़ंक्शन निष्पादित होने पर "ऑब्जेक्ट" टाइप करता है।

+0

धन्यवाद! (लेकिन क्या आप उस 'फ़ंक्शन (मजेदार, इस) के कर्मचारियों के बारे में जानते हैं?) –

+0

हाँ, मुझे अभी एहसास हुआ कि मुझे याद आया, क्षणिक रूप से आने का संपादन करें। –

+2

'फ़ंक्शन (मजेदार/*, यह * *) 'कोडिंग * शैली * है जो इंगित करता है कि यह एक वैकल्पिक पैरामीटर है। 'मजेदार', ज़ाहिर है, बाद में एक प्रतिनिधि समारोह 'fun.call' का उपयोग करके बुलाया गया है,' thisp' को "संदर्भ" के रूप में पास कर रहा है (यानी, यह कार्य निष्पादित होने पर 'इस' का मान बन जाएगा)। –

3

var t = Object(this);

ES5 विनिर्देशन पर आधारित है। यह विशेष रूप से बताता है कि this को Object कन्स्ट्रक्टर में पास किया जाना चाहिए।

यदि आप ES5 spec में निर्दिष्ट सटीक एल्गोरिदम पर बारीकी से देखते हैं तो मोज़िला द्वारा प्रदान की गई विधि इसे लगभग बिल्कुल सही करती है (यह ES3 सुविधाओं द्वारा सीमित है)। यही कारण है कि इस कोड में कुछ quirks लगता है।

नक्शा विधि एक या दो तर्क, निम्न चरणों लिया जाता है के साथ कहा जाता है जब:

  1. Let हे का नतीजा हो

    यहाँ ES5 विनिर्देश है इस मूल्य को तर्क के रूप में पास करने के लिए ToObject को कॉल करना।

  2. लेन को "लंबाई" के साथ ओ [[प्राप्त]] आंतरिक विधि को कॉल करने का परिणाम होने दें।
  3. लेन को ToUint32 (lenValue) दें।
  4. यदि IsCallable (callbackfn) गलत है, तो TypeError अपवाद फेंक दें।
  5. यदि यह एआरजी आपूर्ति की गई थी, तो टी को यह एआरजी दें; अन्य टी को अपरिभाषित होने दें।
  6. एक नई सरणी बनें जैसे अभिव्यक्ति द्वारा नई ऐरे (लेन) जहां एरे मानक नाम के साथ मानक बिल्टिन कन्स्ट्रक्टर है और लेन लेन का मूल्य है।
  7. कश्मीर हो 0.
  8. दोहराएँ करते हैं, जबकि कश्मीर < लेन

    1. दें पी ToString (के) हो।
    2. KPresent को तर्क [पी] के साथ [[HasProperty]] आंतरिक विधि को कॉल करने का परिणाम होने दें।
    3. यदि kPresent सत्य है, तो
      • KValue तर्क [पी] के साथ ओ [[प्राप्त]] आंतरिक विधि को कॉल करने का परिणाम बनने दें।
      • Let बुला का नतीजा हो mappedValue [[कॉल]] के रूप में टी के साथ callbackfn के आंतरिक विधि इस मूल्य और kValue, कश्मीर, और ओ
      • कॉल [[DefineOwnProperty]] आंतरिक विधि युक्त तर्क सूची ए के तर्कों के साथ पीके, संपत्ति वर्णनकर्ता {[[मूल्य]]: मैप्ड वैल्यू, [[लिखने योग्य]]: सत्य, [[गणना]]: सत्य, [[कॉन्फ़िगर करने योग्य]]: सत्य}, और झूठी।
      • बढ़ाएँ k से 1.
  9. वापसी ए

Let हे तर्क के रूप में यह मान गुजर ToObject बुला का नतीजा हो।

सूचना है कि एक कदम विशेष रूप से कहते हैं कि आप बुलाना चाहिए Object(this)

Let [[] जाओ] तर्क साथ हे की आंतरिक विधि "लंबाई" बुला का नतीजा हो lenValue।

लेंस ToUint32 (लेनवैल्यू) दें।

चरण 2 और 3 विशेष रूप से कहते हैं कि मिल t.length तो ToUint32 जो >>> 0 यहाँ के रूप में कार्यान्वित किया जाता है कहते हैं।

वास्तविक हस्ताक्षर विनिर्देश में वर्णित

Array.prototype.map है (callbackfn [, thisArg])

ऊपर हस्ताक्षर callbackfn में एक आवश्यक तर्क है और [ ] एक सरणी है वैकल्पिक तर्कों में से केवल एक thisArg है।

मोज़िला ने function(fun /*, thisp */) { की परिभाषा में यह प्रतिबिंबित किया है कि thisp एक वैकल्पिक तर्क है और यह स्पष्ट है कि यह कोड को देखने से फ़ंक्शन हस्ताक्षर से मामला है।

संबंधित मुद्दे