G
A https://pt.stackoverflow.com/a/90373 explains what's going on, and I'll try to illustrate. Every time addMethod it's called, she keeps how old what is in object[name], create a new function, and keep in place of the old. And every call addMethod create a new old, https://pt.stackoverflow.com/q/1859 .Clearing the code, it becomes clearer:function addMethod(object, name, fn){
var old = object[name];
object[name] = function(){
// ...
};
}
For example, if you have 3 functions, A, B and C, and pass one at a time, you create 3 new functions, each with access to one old different:addMethod(obj, "nomeDoMetodo", A); // old é undefined
addMethod(obj, "nomeDoMetodo", B); // old é uma closure com acesso a A
addMethod(obj, "nomeDoMetodo", C); // old é uma closure com acesso a B
See you have a chain of accesses there. And the function created in addMethod if you take advantage of this, it decides whether to call the past function or the old according to the number of arguments:if(fn.length == arguments.length)
return fn.apply(this, arguments) // chama a função passada, fn
else if (typeof old == 'function')
return old.apply(this, arguments); // chama a função em old, que tem
// acesso ao que foi passado
// na chamada anterior
Suppose A have no arguments, B have one and C have two:function A() {}
function B(um) {}
function C(um, dois) {}
addMethod(obj, "nomeDoMetodo", A); // Chamada #1
addMethod(obj, "nomeDoMetodo", B); // Chamada #2
addMethod(obj, "nomeDoMetodo", C); // Chamada #3
// ATENÇÃO: chamada sem nenhum argumento
obj.nomeDoMetodo();
What happens when we call obj.nomeDoMetodo(), no arguments? Let's see line by line.// Código da função criada na Chamada #3 a addMethod
if(fn.length == arguments.length) // false: fn da Chamada #3 é
// C, que tem 2 argumentos, e agora
// nenhum foi passado
return fn.apply(this, arguments) // (não executa)
else if (typeof old == 'function') // cai aqui
return old.apply(this, arguments); // chama a função em old, que tem
// acesso a B
Then an equal function, but created in Call #2 to addMethod, is invoked:// Código da função criada na Chamada #2 a addMethod
if(fn.length == arguments.length) // false: fn da Chamada #2 é
// B, que tem 1 argumento, e agora
// nenhum foi passado
return fn.apply(this, arguments) // (não executa)
else if (typeof old == 'function') // cai aqui
return old.apply(this, arguments); // chama a função em old, que tem
// acesso a A
And we arrived in the function created in Call #1:// Código da função criada na Chamada #1 a addMethod
if(fn.length == arguments.length) // true: fn da Chamada #1 é
// A, que não tem argumentos.
return fn.apply(this, arguments) // Executa A