43
I know they are functions that do not have the specified name, but what is the purpose?
- Is it possible to recur with anonymous functions? Ex: Fibonacci sequence.
(function(x, y) {
alert(x + y);
})(5, 5); // Função para somar duas variáveis
43
I know they are functions that do not have the specified name, but what is the purpose?
(function(x, y) {
alert(x + y);
})(5, 5); // Função para somar duas variáveis
23
Anonymous functions are very important to understand some of the concepts of how Javascript works, are functions that do not depend on names, are only declared and stored in a variable.
This is an anonymous function: function(){alert('foo');
One of the best practices for using it is to create Javascript Closures, for:
"Knowing Javascript and not knowing Closures is the same thing as knowing Java and not knowing Classes."
That is why the understanding of Closures and Anonymous Functions is of utmost importance.
Closure in English means closure, in order to store, put in a closed place.
That is, it would store a variable in a function that may or may not have parameters. It can return a value and make it immutable, or just perform no return commands.
See how a simple anonymous function would work with a function without arguments:
var anonima = function(){ alert('executou') };
anonima(); //executa a função anônima
Now one with parameter:
var anonima = function(n){ alert(n) };
anonima(2);
We can also create a closure with anonymous functions, such as a sum of two numbers:
var anonima = function(number1){
return function(number2){ alert(number1+number2) };
};
var closure = anonima(2); //salva na variavel closure a funcao que manda o parâmetro number1
closure(3); //manda o parâmetro number2 e executa a função final
Closures becomes great for storing some operations in variables that call different functions returning an operation or function result.
Another very good thing of the Closures would be the creation of encapsulated classes, as for example, a class of a Company:
function Empresa(nome){
//privates
var _funcionarios = [];
var _ordenaFuncionarios = function(){
return _funcionarios.sort();
}
//public's
return {
adicionaFuncionario: function(funcionario) {
_funcionarios.push(funcionario);
//return this;
},
meusFuncionarios: function(){
return _ordenaFuncionarios(_funcionarios).join(", ");
}
};
}
And see how easy it becomes to add employees, and print them ordered:
var p = new Empresa("Foo Ltda");
p.adicionaFuncionario("João da Silva");
p.adicionaFuncionario("Maria da Rosa");
alert(p.meusFuncionarios()); //João da Silva, Maria da Rosa.
Notice that you have "Return this" commented, uncomment test and so you will be able to use method chaining in this way:
var p = new Empresa("Foo Ltda");
alert(p.adicionaFuncionario("João da Silva")
.adicionaFuncionario("Maria da Rosa")
.meusFuncionarios()); //Joao da Silva, Maria da Rosa
Another thing, you can avoid creating global variables using Closures, as follows:
cor = "azul";
(function(){ //função anônima
var cor = "#FF0000";
document.body.style.background = cor; //deixa o fundo da pagina vermelho
})();
alert(cor); //azul
Javascript closures are very good for a lot of things, anonymous functions too. As you can see, it’s worth taking a look at :)
20
You can implement using recursion yes, just use the variable itself to which you assigned the function and call it:
var fibonacci = function(num)
{
if(num==1 || num==2)
return 1;
else
return fibonacci(num-1) + fibonacci(num-2);
};
To pass as if it were any object
The purpose of an anonymous function is exactly to allow you to pass it as if it were any object, which you can assign to a variable, regardless of whether there is a name for the function.
Protecting variables using an anonymous function
Protecting variables against misuse is one of the purposes that ended up meeting for anonymous functions. It would be the equivalent of creating private members, as is possible in several languages.
In the Fibonacci example, if you want to protect the variable used to assign the function, you could do so:
var fibonacci = (function() {
var fnc = function(num)
{
if(num==1 || num==2)
return 1;
else
return fnc(num-1) + fnc(num-2);
};
return fnc;
})();
This way, there would be no way to change the internal dependency of the function after it has already been created. It will no longer be possible to change the variable fnc
, because it is within the context of the anonymous function, whose reference is lost, soon after calling the same.
Basic structure:
var obj = (function() {
// declarações a serem protegidas
var a, b, c;
// retornando um objeto construído a partir de a, b e c
return obj;
})();
I think the question is not about Fibonacci but about Anonimas functions, Fibonacci was an example of use case.
I think the real question was: "How to use recursion in an anonymous method, since it does not have a name?"
agree, I think it was worth editing the title :)
Not to be pedantic, but when you assign a function to a variable, does it stop being anonymous? (i.e. you gave it a name) Your answer is technically correct, but everything described here would be equally possible with appointed functions.
What about protecting variables within an anonymous function? I mention that the function is lost immediately after calling it... something like (function () { })()
@Miguelangelo OK, in this case there is in fact a small advantage. Although it is possible to do (function nome() { })()
and the variables within it would remain protected, the function itself would be accessible through the name and could be used incorrectly.
13
In Javascript, functions are called "first class members". This means you can instantiate them, assign them to variables, or even create them dynamically at runtime (note: 99% of the time I don’t recommend). Each instantiated function is carrying a class object Function
.
An anonymous function is not very different from a named function. These two definitions are in fact equivalent:
function foo() { return "bar"; }
var foo = function() { return "bar"; }
Not. The apparent difference (as pointed out in Reply by @Gabriel Gartz) is due to the fact that in Javascript the variable settings are automatically brought to the top of your lexical scope.
That means when the interpreter sees:
console.log(naoAnonima()); // 'foo'
console.log(anonima()); // undefined
var anonima = function () {return 'bar';};
function naoAnonima() {return 'foo'; }
It automatically converts to:
var anonima; // A definição da variável veio pra cima, a atribuição não
function naoAnonima() {return 'foo'; } // A definição da função veio pra cima
console.log(naoAnonima()); // Aqui naoAnonima já está definida
console.log(anonima()); // A variavel anonima existe, mas ainda não aponta pra uma função
anonima = function () {return 'bar';}; // A partir daqui anonima refere-se a uma função
You don’t always need a name for your function. It’s that simple! Whether you’re going to use the newly defined function in an event handler, or in a callback for Ajax, etc., there is no need to put this function in a variable/give it a name. Just create the function and assign it where needed (first class, remember?).
window.onload = function() { /* essa função não precisa de um nome */ };
There is a trick more theoretical than practical interest called "Y Combinator", that I will not demonstrate here, who is interested here has some links explanatory (in English). It basically allows recursion to be implemented without any variable or function statements. That is, unlike the other answers - that "cheat" a little, giving a name to its anonymous function (!) - this solution works even if there is no reference to the function itself.
Y(function (fac) {
return function (n) {
return n <= 2 ? n : n * fac(n - 1);
};
})(5); // 120
But if this "cheating" is admitted (in practice, there is not much benefit in "smart" solutions - better that they are clear and efficient), then to get a recursive effect in an anonymous function just make it receive as argument a function:
var fat = function(fn, n) {
if ( n <= 2 )
return n;
return n * fn(n - 1);
};
...and pass herself as argument in your call!
fat(fat, 5); // 120
That is, the function does not is recursive (because you could call it passing something else as first argument), but it behaves recursively.
+1 by the Commission
6
Functions Anonimas they do not have an identification in the javascript execution scope, but can be assigned to variables, gaining access only when this variable is accessible.
Example:
console.log(naoAnonima()); // 'foo'
console.log(anonima()); // undefined
var anonima = function () {return 'bar';};
function naoAnonima() {return 'foo'; }
console.log(naoAnonima()); // 'foo'
console.log(anonima()); // 'bar'
As can be seen in the example, the anonymity function it is only accessible so the variable also.
If you do not use the strict mode (use strict
) you can access the reference of an anonymous function through the property Arguments.callee exposed in its context.
Example:
function () {
arguments.callee; // Aqui está referencia pra sua função
};
Using strict mode, this will cause you an exception.
So if you are to implement the Fibonnaci example, you can first declare a variable that will store the reference of your anonymity function and use it within the anonymity function.
var fib = function (n) {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
};
In this case fib
exists within the anonymity function because when the function is being accessed by itself, the variable has already been assigned. Allowing recursion.
A textual example of ES3 was to use the arguments.callee
for that reason:
(function (n) {
if (n <= 2) return 1;
return arguments.callee(n - 1) + arguments.callee(n - 2);
})(10); // 55
Note that no function has been assigned to any variable. That is, after it has been executed and finished, it will be marked by Garbage Collector to be eliminated, in which case there is no further reference to it.
At ES5 you do not have access to property arguments.callee
in strict mode, but you can hide the function that applies recursion within an anonymous function if you do not want to expose this one. Example:
(function (n) {
// fib não está exposto
return (function fib(n) {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
})(n);
})(10); // 55
In this case even if you name the anonymity function, its internal Fib function is inaccessible.
Purpose:
The functions Anonimas exist to streamline and simplify coding, for example, if you want to isolate a range of variables, you can simply auto-execute an anonymous function for this.
It is very common in javascript to assign functions to properties or pass them as an argument, the Anonimas functions simplify coding and you do not need to name them to do these assignments, making your code simpler.
+1 for the use of arguments.callee
. Although in practice not recommended, this was the only example of anonymous recursive function in all responses (the other "cheating" a little - giving a name to the anonymous function!).
Thanks @mgibsonbr, put only for educational purposes even, do not recommend the use.
@mgibsonbr see my answer now is no longer cheating and do not use the arguments.callee
:P
3
It also fits the definition of Higher order function javascript
They receive one or more functions as arguments or have a function as output. Through them it is possible to create what are called functions Factories that are functions that from other functions are able to perform more complex actions. The context itself already tells us : Unnamed functions, moreover, it includes as its main feature the concept of recursiveness.
<script>
var n = parseInt(prompt('Entre com a seleção da cor : '));
(function(n){
var cor = [
'#FF0000',
'#000000',
'#C9CCCC'
];
for(var i = 0; i < cor.length; i++) {
document.body.style.background = cor[i + n];
break;
}
if (n >= cor.length)
alert('Error = Cor da seleção deve ser < ' + cor.length);
else
alert('Cor Selecionada : ' + cor[i + n] + ' ');
})(n);
</script>
Browser other questions tagged javascript anonymous-function
You are not signed in. Login or sign up in order to post.
I don’t think you understand very well what are closures. Or maybe you are - the second half of your answer describes closures very well. However, what you refer to as "storing a function in a variable" is not closures, but "first class functions". In other words, a language may have first-class functions but have no lexical scope - and therefore not support closures.
– mgibsonbr
You meant that the functions that I added at the beginning that were not encapsulated are not closures?
– Paulo Roberto Rosa
funcaoInterna
is a closure. The two internal functions toEmpresa
also are. The rest are not. To be a closure, the function has to reference some variable of the lexical scope above of it (e.g., whenfuncaoInterna
accessnumber1
- which belongs to the lexical scope offuncaoExterna
).– mgibsonbr
There’s a typo there in the first example, right? I think we need to close
function(){alert('foo');
. . .– brasofilo