I know they are functions that do not have the specified name, but what is the purpose?
- Is recursion possible with anonymous functions? Ex: Fibonacci sequence.
(function(x, y) {
alert(x + y);
})(5, 5); // Função para somar duas variáveis
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
You can implement using recursion yes, just use the variable you assigned the function to and call it:
var fibonacci = function(num)
{
if(num==1 || num==2)
return 1;
else
return fibonacci(num-1) + fibonacci(num-2);
};
Pass as if it were any object
The purpose of an anonymous function is to allow it to pass as if it were an 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 you've just met for anonymous functions. It would be the equivalent of creating private members, as is possible in many languages.
In the fibonacci example, if you want to protect the variable used to assign the function, you could do this:
var fibonacci = (function() {
var fnc = function(num)
{
if(num==1 || num==2)
return 1;
else
return fnc(num-1) + fnc(num-2);
};
return fnc;
})();
In this way, you would not be able to change the internal dependency of the function after it has already been created. It will no longer be possible to change the fnc
variable, since it is within the context of the anonymous function whose reference is lost after calling it.
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;
})();
Anonymous functions are very important to understand some of the concepts of JavaScript operation, they 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 , because:
"Knowing JavaScript and not knowing Closures, is the same thing as knowing Java and not knowing Classes."
For this reason, the understanding of Closures and Anonymous Functions is of the utmost importance.
Closure in English means closure, in the sense of keeping, put in a closed place.
That is, you would store a variable in a function that may have parameters or not. It can return a value and make it immutable, or else just perform commands with no return.
Here's how a simple anonymous function would work with a function with no 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 become great for storing in some variables operations that call different functions by returning an operation result or function.
Another very good thing about Closures would be the creation of encapsulated classes, such as a Company class:
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 is to add employees, and print them sorted:
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.
Note that you have "return this" commented, uncomment test and so you will be able to use method chaining like this:
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 as well. As you can see, it's worth studying about it:)
In JavaScript, functions are said to be "first class members". This means that you can instantiate them, assign them to variables, or even create them dynamically at runtime (note: 99% of the time I do not recommend). Each instantiated function is carrying an object of class 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"; }
No . The apparent difference (as pointed out in the @Gabriel Gartz response) is due to the fact that in JavaScript the variable definitions are automatically brought to the top of their lexical scope.
This means that 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 do not always need a name for your job. It's that simple! If you are going to use the newly defined function in an event handler, or 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 you need it (first class, remember?).
window.onload = function() { /* essa função não precisa de um nome */ };
There is a more theoretical rather than practical interest called " Y Combinator , that I will not show here, anyone interested here has some links explanatory (in English). It basically allows recursion to be implemented without any variable or function declaration. 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 - rather than being clear and efficient), then to get a recursive effect on an anonymous function, just get it as a function argument:
var fat = function(fn, n) {
if ( n <= 2 )
return n;
return n * fn(n - 1);
};
... and pass herself as an argument in your call!
fat(fat, 5); // 120
That is, the function is not recursive (since you could call it by passing something else as the first argument), but it behaves recursively.
Anonymous functions they do not have an ID in the execution scope of javascript, however they can be assigned to variables, earning by becoming accessible 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 anonymous function is only accessible as soon as the variable as well.
If you do not use strict mode ( use strict
) you can access the reference of an anonymous function by means of the arguments.callee exposed in your context.
Example:
function () {
arguments.callee; // Aqui está referencia pra sua função
};
Using strict mode, this will cause you an exception.
So if you implement the fibonnaci example, you can first declare a variable that will save the reference of your anonymous function and use it within the anonymous function.
var fib = function (n) {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
};
In this case fib
exists inside the anonymous function because when the function is being accessed by itself, the variable has already been assigned. Enabling recursion.
One way to do just a didactic example of ES3 was to use arguments.callee
for this:
(function (n) {
if (n <= 2) return 1;
return arguments.callee(n - 1) + arguments.callee(n - 2);
})(10); // 55
Notice that no function was assigned to the function. That is, after it has been executed and finalized, it will be marked by the garbage collector to be deleted, because in that case there is no longer any reference to it.
In ES5 you do not have access to the arguments.callee
property in strict mode, but you can hide the function that applies recursion within an anonymous function if you do not want to expose it. 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 anonymous function, its internal fib function is inaccessible.
Purpose:
Anonymous functions exist to streamline and simplify encoding, for example if you want to isolate a scope of variables, you can simply auto-execute an anonymous function for that.
It is very common in javascript to assign functions to properties or pass them as an argument, anonymous functions simplify coding and you do not need to name them to make these assignments, leaving your code simpler.
It also fits into the Javascript command setting setting
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 which are functions that from other functions are able to perform more complex actions. The context itself also tells us: Unnamed functions, moreover, it includes as main characteristic the concept of recursion.
<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>