9

The book Learning JavaScript defines anonymous functions as follows...

Functions are objects. As such, you can create them - just like a String or Array or other type - by using a constructor and assigning the function to a variable. In the following code, a new function is created using the Function constructor, with the function body and argument passed in as arguments:

var sayHi = new Function("toWhom", "alert('Hi' + toWhom);");

This type of function is often referred to as an anonymous function because the function itself isn't directly declared or named.

Is this the correct definition of an "anonymous function" in JavaScript? If not, what is an anonymous function, and is there any difference between an anonymous function and a function literal?

Community
  • 1
  • 1
Richard JP Le Guen
  • 28,364
  • 7
  • 89
  • 119
  • This isn't the function type most commonly referred to as 'anonymous'. That would be a `FunctionExpression` being used with no name, eg: `var fn = function(){..}` vs `var fn = function fn(){...}`. – Sean Kinsey May 02 '11 at 13:28
  • I don't think this is a good book, but I can only rely on this one snippet for my judgment. – Marcel Korpel May 02 '11 at 13:40

5 Answers5

18

Function expressions and function declarations

Since you are interested in functions, here is some important stuff to know.

var abc = function() { ... } is known as a function expression. The variable will be assigned that anonymous function at execution time, though its variable declaration will be hoisted to the top of the current execution context (scope).

However, a function expression can be given a name too, so that it can be called within its body to make it recursive. Keep in mind IE has some issues with this. When you assign it a name, it is most definitely not an anonymous function.

A function such as function abc() { ... } is known as a function declaration. Its definition is hoisted to the top of its scope. Its name is available within it and its parent's scope.

Further Reading.


Your Example

It is an anonymous function, but assigned to the variable sayHi.

As Šime Vidas mentions, a new Function object is instantiated with the new operator, and the arguments and function body are passed in as strings. The resulting object is assigned to sayHi.

The real world use of creating a function using this method is rare (though it may be just to help show that functions are objects). I also believe passing its arguments list and function body as a string will invoke an eval() type function, which is rarely good when a much better construct is available.

Also, functions created with Function do not form a closure.

I would only use this method if for some reason I needed to create a Function with its arguments and/or body only available to me as a string.

In the real world, you'd do...

var sayHi = function(toWhom) {
   alert('Hi' + toWhom);
};

Also refer to comments by Felix and Šime for good discussion and further clarification.

Community
  • 1
  • 1
alex
  • 479,566
  • 201
  • 878
  • 984
  • Therefore an anonymous function and a function literal mean the same thing? – Richard JP Le Guen May 02 '11 at 13:08
  • @Richard I think that is subjective. – alex May 02 '11 at 13:12
  • @alex - Can you elaborate? I think that's the heart of what I'm trying to understand. – Richard JP Le Guen May 02 '11 at 13:17
  • @Richard Sorry, I wasn't 100% sure how to answer that. A function literal such as `function() { ... }` would be the closest to definition of an *anonymous function* I believe. – alex May 02 '11 at 13:18
  • *so is it still anonymous?* Yes, because the function has no name. The name of the variable you assign the function to is unrelated to the function itself.... +1 :) – Felix Kling May 02 '11 at 13:19
  • @Richard No. An anonymous function can be created (1) by using the `Function` constructor or (2) by using a function expression (= function literal). – Šime Vidas May 02 '11 at 13:23
  • @Felix Thanks Felix for confirming that. :) – alex May 02 '11 at 13:23
  • 3
    @Richard: I haven't heard *function literal* that often. Important is the difference between *function expression* and *function declaration*. If we consider a function expression as function literal, then no, it is not the same. As @alex already explained, there are *named function expressions* which are not anonymous anymore, the functions have a name. But they are still function expressions (= function literals). – Felix Kling May 02 '11 at 13:23
  • 1
    @alex *"This is known as a function expression."* - No, it's a function object created by using the Function constructor. A function expression is this: [`function Identifieropt ( FormalParameterListopt ) { FunctionBody }`](http://es5.github.com/#x13) – Šime Vidas May 02 '11 at 13:29
  • @Felix Kling - Ohhhh. That seems to make the most sense to me; if you post that as an answer, I think I would like to accept it. – Richard JP Le Guen May 02 '11 at 13:32
  • @Šime I think my answer has become difficult to follow and not aligned with my thoughts, I'll edit :) – alex May 02 '11 at 13:32
  • @Šime @Felix How's that guys? :) – alex May 02 '11 at 13:39
  • @alex: Good for me :) Maybe you can stress that *named* function expressions are not anonymous (obviously but for clarity). But I can't give you another +1 ;) – Felix Kling May 02 '11 at 13:42
  • @Felix Hehe. Thanks for your follow up too, I really appreciate it (and it teaches *me* stuff, most importantly) :) – alex May 02 '11 at 13:43
  • @Richard: I think @alex did a pretty good job to cover most of the aspects regarding functions (object, declaration, expression) ;) And my comment won't go away anyway :) – Felix Kling May 02 '11 at 13:45
  • Are you going to add something about Mozilla's `FunctionStatements`? ;-) – Marcel Korpel May 02 '11 at 14:10
  • @Felix Kling - I agree @alex's answer is good... except "It is an anonymous function, but assigned to the variable `sayHi`" doesn't make sense to me. Once it is assigned to a variable, I don't see how it is still anonymous. In JavaScript `function myFunk() {...}` is the same as `var myFunk = function() {...}`, no? Therefore assigning an anonymous function to a variable is the same as declaring it and naming it and therefore no longer anonymous. – Richard JP Le Guen May 02 '11 at 14:10
  • @Marcel I can't get too off topic :) – alex May 02 '11 at 14:12
  • @Richard: no, it's still anonymous. Please read that article Alex mentioned, especially http://kangax.github.com/nfe/#names-in-debuggers – Marcel Korpel May 02 '11 at 14:15
  • @Richard: Then what would be the name of the function when you do `var a = function() {}; b = a;` ? The name of the variable is not the name of the function. – Felix Kling May 02 '11 at 14:36
  • @Felix Kling - By the same logic, `function a() { alert("First: a"); }; a(); a = function() { alert("Second: b"); }; a();` Which function is `a` now? – Richard JP Le Guen May 03 '11 at 14:10
  • @Felix Kling - ...but I think I'm beginning to see what you're saying with "The variable name is not the name of the function". – Richard JP Le Guen May 03 '11 at 14:13
  • ... although if "the name of the variable isn't the name of the function" doesn't sit right with me when I run something like `function a() { alert("First: a"); }; alert(a.toString());`. Does the name of the function implicitly create a variable then? – Richard JP Le Guen May 03 '11 at 14:21
  • 1
    @RichardJPLeGuen: I would say a function declaration adds a new symbol to the scope where the function is defined. This symbol has the same name as the name of function. Consider another example: `function a(){}; var b = a;`. Although the function was assigned to `b`, its name is still `a`. I suggest you have a look at the [`name` property](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name) of a function (works in Chrome too) to see what statement generates what kind of function. – Felix Kling May 03 '11 at 15:56
1

I think a broader and more accepted definition of an anonymous function is a function that is created without a name.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
1

An anonymous function is simply a function with no name.

function(a, b){
  return a + b;
}

The above code would be useless as it has no name to which you could call it with. So they are usually assigned to a variable.

var func = function(a, b){
  return a + b;
}

This is helpful because you can pass an anonymous function to another function or method without having to create the function before hand, as demonstrated below.

function bob(a){
  alert(a());
}

bob(function(){
  return 10*10;
})
Ryan
  • 3,726
  • 3
  • 26
  • 38
  • 1
    @Sean_Kinsey Exactly, that's why I stated it is useless, and went on to show how it can be used in conjunction with other code. – Ryan May 02 '11 at 13:24
1

This:

new Function("toWhom", "alert('Hi' + toWhom);")

and this:

function(toWhom) { alert('Hi' + toWhom); }

are two expressions that produce the same result - they return a new anonymous function object.

The second expression (and only the second expression) is called a function expression. You may also call it a function literal (although we could argue that a function declaration is also a function literal).

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
0
function foo(){
    alert("i'm foo, nice to meet you!");
}
var bar = function(){
    alert("I am an anonymous function assigned to the variable \"bar\"");
}
gion_13
  • 41,171
  • 10
  • 96
  • 108
  • So an anonymous function is a synonym for a function literal? – Richard JP Le Guen May 02 '11 at 13:12
  • 2
    @Richard - there is no such thing as a 'function literal' unless you refer to the formal syntax of a function in javascript. The alternative would be functions created using the `Function` constructor. In js you have three kinds of ways to create functions, using FunctionDeclaration's (name mandatory), FunctionExpressions (name optional) and FunctionConstructor (name optional). The latter two have optional names as these can be used in expressions and thus be referred to as an operand. – Sean Kinsey May 02 '11 at 13:26