Can't understand this Javascript function (function overload)

I read "Javascript Ninja Secrets" and stumbled upon an example that I cannot fully understand. The same example was given by someone else here, but their doubts are different from mine. Here is an example:

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);

    };
}

This is an example of function overloading used this way:

var ninja = {};
addMethod(ninja,'whatever',function(){ /* do something */ });
addMethod(ninja,'whatever',function(a){ /* do something else */ });
addMethod(ninja,'whatever',function(a,b){ /* yet something else */ });

I have a clear understanding of the scope, closure and use of apply (). My doubts:

  • fn.length will return the number of parameters defined in fn. Will the .length argument return the number of arguments? An existing feature?
  • But if so, and they coincide, why then will he use a new function, not an existing one?
  • If the .length arguments return the number of the given function, then when will they differ?
  • 10 , , 10- , "" ?
  • .

, , - , . , .

+4
5

fn.length , fn. arguments.length ? ?

. arguments - , . , .

, :

10 , , 10- , "" ?

addMethod :

function addMethod(object, name, fn) {

  var old = object[name];
  // Get the old function corresponding to this name. Will be "undefined"
  // the first time "addMethod" is called.


  object[name] = function(){
  // Now, assign object[name] to a new function.
  // The critical part of this function is that "old" is captured inside of
  // this function and will be available any time the function is called.

       if (fn.length == arguments.length)
       // if the number of parameters belonging to the function we've added
       // matches what was passed in, call "fn"
          return fn.apply(this, arguments)

       else if (typeof old == 'function')
       // Otherwise if there another function with this name
       // call it instead.
          return old.apply(this, arguments);

    };
}

, addMethod fn old. , , , old.

addMethod(ninja,'whatever',function(){ /* do something */ });
// old === undefined

addMethod(ninja,'whatever',function(a){ /* do something else */ });
// old === function #1

addMethod(ninja,'whatever',function(a,b){ /* yet something else */ });
// old === function #2

addMethod ninja.whatever , # 3, , old ( # 2), # 3 .

, :

function #3 (a,b)
function #2 (a)
function #1 ()

old .

, , ninja.whatever(). " " .

  • , whatever, # 3. β„–3, fn.length != arguments.length .. old ( # 2).
  • , # 2. , # 2, fn.length != arguments.length old ( # 1) .
  • , # 1. fn.length == arguments.length , , .
+2

:

//replace object[name] with a wrapper that either calls the passed-in 
//function (fn) or the old value of object[name]
function addMethod(object, name, fn) {

  //store object[name]    
  var old = object[name];



  object[name] = function(){

        //if the wrapper is called with as many arguments as is the arity of the passed in function (fn), call the passed in function (fn)
       if (fn.length == arguments.length)

          return fn.apply(this, arguments)

       //otherwise call the old value of object[name] but only if it is a function
       else if (typeof old == 'function')

          return old.apply(this, arguments);

    };
}
+1

, , . , , old, object, name fn. , "" . "" , , , .

function addMethod(object, name, fn) {

  // Get a reference to the existing method name.
  var old = object[name];

  /*
    Write over the method name with a new method
    that checks for a specific argument length.
    If the method is called with a different
    argument length and "old" exists call the
    old method.
  */

  object[name] = function(){

       if (fn.length == arguments.length)

          return fn.apply(this, arguments)

       else if (typeof old == 'function')

          return old.apply(this, arguments);

    };
}
+1

function.length - , , . arguments.length - , , , ; . arguments , , . ( , ). , , . console.log() , . arguments - arguments. , addMethod. old , . , old ( - / ).

+1

. arguments.length , ,

object[name] = function(){

The method is "stored" in the object ninjadeclared in your first line of code, and passed to subsequent calls.

0
source

All Articles