"First of all, thank you for the mental exercise".
At first it was complicated, because of logic, since it had to set to false whenever it signed a new value, or even if it left parameters missing.
In the end I got this here:
<script>
function bar(){
//foo(4); // 4
//foo(4, 4) // 8
//foo(4, function(soma){alert(soma);}) // alert(4)
foo(4, 4, function(soma){alert(soma);}) // alert(8)
}
function foo(argA, argB, callback){
var soma;
var argA = (typeof argA !== 'undefined') ? argA : 0;
var argB = (typeof argB !== 'undefined') ? argB : 0;
var callback = (typeof callback !== 'undefined') ? callback : false;
if(argA && argB && callback === false){
if(typeof argB === "function"){
callback = argB;
soma = argA;
} else {
soma = argA + argB;
}
} else if(argA && argB && callback) {
soma = argA + argB;
} else {
soma = argA;
}
if(callback && typeof callback === "function"){
return callback(soma);
} else {
return soma;
}
}
</script>
The function foo
in this case, it is the function responsible for the sum, being:
foo(arg1,[arg2],[callback]) { // magia }
When creating functions of this type, you should take into account that javascript functions:
- Do not specify data type for arguments.
- Do not verify which types of arguments have been passed.
- No verification of number of arguments received.
Default of the unsigned:
- If the function is called with fewer arguments than the declared ones, the missing elements are set to : Undefined.
The first parameter is required, or the function fails, in this example I did not create conditions in case the first parameter was not provided, so instead of returning false
if no parameter is given, the function will return 0
as the sum.
The JS is not my strong suit, however, I think the function is well reduced and the logic is correct.
Example of use:
function bar(){
//foo(4); // 4
//foo(4, 4) // 8
//foo(4, function(soma){alert(soma);}) // alert(4)
foo(4, 4, function(soma){alert(soma);}) // alert(8)
}
function foo(argA, argB, callback){
var soma;
var div = document.getElementById('demo');
var argA = (typeof argA !== 'undefined') ? argA : 0;
var argB = (typeof argB !== 'undefined') ? argB : 0;
var callback = (typeof callback !== 'undefined') ? callback : false;
if(argA && argB && callback === false){
if(typeof argB === "function"){
callback = argB;
soma = argA;
} else {
soma = argA + argB;
}
} else if(argA && argB && callback) {
soma = argA + argB;
} else {
soma = argA;
}
if(callback && typeof callback === "function"){
return callback(soma);
} else {
//return soma;
div.innerHTML = soma;
}
}
<body>
<button id="bt" onclick="bar();">Clica-me</button>
<p id="demo"></p>
</body>
Below the same function, for the same purpose, using the object Arguments to pass the parameters, such as the @bfavarreto example, or as @Guilherme Lautert suggested, also streamline the order of functions:
Using the method Sort(), can create the same effect by placing the function always in the last position, making the function has its normal stroke.
<script>
function foo(){
var div = document.getElementById('sum');
div.innerHTML = soma(2,3,4,3); // Retorna: 8
//return soma(2,2,function(i){alert(i);}); // Retorna: alert(4)
//return soma(); // Retorna: 0
//return soma(1,function(i){alert(i);},5); // Retorna: alert(6)
//return soma(1,5, function(i){alert(i);}); // Retorna: alert(6)
}
function soma(){
var array = Array.prototype.slice.call(arguments);
var len = arguments.length;
//console.log(array.length); // Retorno: (int)N argumentos contando com o callback;
var array = array.sort(); // utilizando o método sort() a função vai estar sempre na última posicao
var callback = typeof array[len-1] == 'function' ? array.pop() : false;
var Newlen = array.length;
var soma = 0;
// Somar os valores
for(i=0; i<Newlen;++i){
soma += Number(array[i]);
}
//console.log(array.length); // Retorno: (int)N argumentos sem o callback;
//Controlar o retorno
if(callback){
// Com callback
return callback(soma);
} else {
// Sem callback
return soma;
}
}
</script>
<body>
<div id="sum"></div>
<button onclick="foo();">Somar</button>
</body>
The object Arguments is similar to an array, but is not an array, the only array property it has is the size (length). Using the method Slice in it, prevents optimizations in Javascript engines. It is recommended to create an array iterating the object Arguments.
Related (almost? dup...): http://answall.com/questions/4293/como-crea-uma-fun%C3%A7%C3%A3o-in-javascript-that-accepts-an-n%C3%Bamero-arbitr%C3%A1rio-de-argument
– bfavaretto