2013-03-04 15 views
5

मैं Secrets of the JavaScript Ninja पढ़ रहा था और मैं इस कोड है जो एक समारोह अधिभार का उत्पादन देखा:जावास्क्रिप्ट और समारोह अधिभार स्पष्टीकरण

function addMethod(object, name, fn) 
{ 
     var old = object[name]; 
     object[name] = function() 
     { 
       if(fn.length == arguments.length) return fn.apply(this, arguments) 
       else if(typeof old == 'function') return old.apply(this, arguments); 
     }; 
} 

function Ninjas() 
{ 
     var ninjas = ["Dean Edwards", "Sam Stephenson", "Alex Russell"]; 
     // addMethod is defined in Listing 2-28 
     addMethod(this, "find", function() 
     { 
       return ninjas; 
     }); 
     addMethod(this, "find", function (name) 
     { 
       var ret = []; 
       for(var i = 0; i < ninjas.length; i++) 
       if(ninjas[i].indexOf(name) == 0) ret.push(ninjas[i]); 
       return ret; 
     }); 
     addMethod(this, "find", function (first, last) 
     { 
       var ret = []; 
       for(var i = 0; i < ninjas.length; i++) 
       if(ninjas[i] == (first + " " + last)) ret.push(ninjas[i]); 
       return ret; 
     }); 
} 

var ninjas = new Ninjas(); 


assert(ninjas.find().length == 3, "Finds all ninjas"); 
assert(ninjas.find("Sam").length == 1, "Finds ninjas by first name"); 
assert(ninjas.find("Dean", "Edwards").length == 1, "Finds ninjas by first and last name"); 
assert(ninjas.find("Alex", "X", "Russell") == null, "Does nothing"); 

function assert(a,b) 
{ 
    if (a==true) console.log(b) ; else console("----"); 
} 

जहां तक ​​मैं समझता हूँ, addMethod हमेशा समारोह के old मूल्य (बंद) के माध्यम से रहता है ।

तो अंत में, वहाँ एक समारोह जो एक शर्त है की जांच करता है, और अगर यह विफल रहता है, यह old समारोह है जो बदले में एक ही बात करता invokes।

हालांकि मुझे arguments.length के मूल्यांकन को समझ में नहीं आता है (मुझे function().length और argument.length के बीच अंतर पता है)।

कौन सा आयत arguments का संदर्भ है?

enter image description here

मैं डीबगर में यह पता लगाया है, और मैं उलझन में हो रही है, क्योंकि पहली बार में, समारोह रजिस्टरों (ताकि है, लेकिन बाद में यह शुरू हो जाती है तो अब एक और तर्क हैं।

कैसे है कि काम कर रहे

JSBin

+0

[पर 'arguments' MDN डॉक्स] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments) सहायता के हो सकता है। –

उत्तर

5

लेकिन करता है बहस के लिए संदर्भित करता है?: (जो आयत?)

2 - object[name] = function()

arguments हमेशा भीतरी सबसे function घोषणा/अभिव्यक्ति के लिए वस्तु के पास भेजेगा। किसी भी बाहरीfunction एस, जैसे कि addMethod(object, name, fn), छायांकित और प्रदान किए जा सकेंगे क्योंकि वे सभी समान पहचानकर्ता का उपयोग करते हैं।


यह में (arguments.length) पारित तर्क की संख्या के लिए नामित किया गया है कि तर्क की संख्या (fn.length) की तुलना है, 1 मिलान का उपयोग। ताकि:

ninjas.find()      // (0 == 0), uses `function()` 
ninjas.find("Sam")     // (1 == 1), uses `function (name)` 
ninjas.find("Dean", "Edwards")  // (2 == 2), uses `function (first, last)` 
ninjas.find("Alex", "X", "Russell") // (? == 3), no match, returns `undefined` 
+0

+1 यह उल्लेखनीय हो सकता है कि पहली बार ('ninja.find()'), ** 3 अधिभार ** फ़ंक्शन देखता है और फिर ** 2 अधिभार ** फ़ंक्शन को सक्रिय करता है और जब इसे अभी भी नहीं मिलता है, यह फिर से चला जाता है .... और फिर ... –

+0

@RoyiNamir ठीक है, यह एक मैच है जब तक यह "* अधिभार * * सक्रिय नहीं करता है। यह केवल 'addMethod' के भीतर बनाए गए अज्ञात फ़ंक्शन को कॉल कर रहा है। यह 'पुराने' संदर्भों की एक तरह की लिंक्ड-लिस्ट लूप के रूप में कार्य करता है, जो बंद होने के "* खरगोश छेद *" पर चढ़ते हैं जब तक कि यह या तो कोई मिलान न हो या नीचे तक पहुंच जाए। –

+0

'यह'' fn.apply में 'यह' ऑब्जेक्ट में 'ऑब्जेक्ट' को संदर्भित करता है [name] = {..} 'दाएं? –

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