These are the first few lines in the MicrosoftAjax.debug.js file.
What are they doing with the syntax? Specifically line 3.
Function.__typeName = 'Function';
Function.__class = true;
Function.createCallback = function Function$createCallback(method, context) {
This is ordinary code which happens to have a $ character in a function name.
The expression function Function$createCallback(method, context) { ... } is a named function expression; it evaluates to a function named Function$createCallback.
Unlike many languages, the $ character is perfectly legal in a Javascript identifier (see jQuery), so this is a normal function with a somewhat unusual name.
The code assigns that function to create a createCallback property on the Function object.
(The property happens to be a function; Javascript functions are no different from variables)
Related
We have two different way for doing function expression in JavaScript:
Named function expression (NFE):
var boo = function boo () {
alert(1);
};
Anonymous function expression:
var boo = function () {
alert(1);
};
And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?
In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)
Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.
(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)
One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.
The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:
var boo = function() { /*...*/ };
(or it could be let or const rather than var), or
var obj = {
boo: function() { /*...*/ }
};
or
doSomething({
boo: function() { /*...*/ }
});
(those last two are really the same thing), the resulting function will have a name (boo, in the examples).
There's an important, and intentional, exception: Assigning to a property on an existing object:
obj.boo = function() { /*...*/ }; // <== Does not get a name
This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.
Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.
For example, consider this code:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.
It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:
Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
(emphasis mine)
You should always use named function expressions, that's why:
You can use the name of that function when you need recursion.
Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.
When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.
If a function is specified as a Function Expression, it can be given a name.
It will only be available inside the function (except IE8-).
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
This name is intended for a reliable recursive function call, even if it is written to another variable.
In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:
var test = function sayHi(name) {
Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
alert( test.name ); // foo
};
test();
Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.
Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.
We have two different way for doing function expression in JavaScript:
Named function expression (NFE):
var boo = function boo () {
alert(1);
};
Anonymous function expression:
var boo = function () {
alert(1);
};
And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?
In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)
Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.
(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)
One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.
The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:
var boo = function() { /*...*/ };
(or it could be let or const rather than var), or
var obj = {
boo: function() { /*...*/ }
};
or
doSomething({
boo: function() { /*...*/ }
});
(those last two are really the same thing), the resulting function will have a name (boo, in the examples).
There's an important, and intentional, exception: Assigning to a property on an existing object:
obj.boo = function() { /*...*/ }; // <== Does not get a name
This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.
Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.
For example, consider this code:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.
It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:
Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
(emphasis mine)
You should always use named function expressions, that's why:
You can use the name of that function when you need recursion.
Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.
When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.
If a function is specified as a Function Expression, it can be given a name.
It will only be available inside the function (except IE8-).
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
This name is intended for a reliable recursive function call, even if it is written to another variable.
In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:
var test = function sayHi(name) {
Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
alert( test.name ); // foo
};
test();
Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.
Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.
The following line is known as a function expression in JavaScript. Does it contain within it a function declaration?
var foo = function() {};
Edit: edited for clarity.
No, it does not. Both function expressions and function declarations do define functions, and contain the function keyword.
How they differ is basically determined where they appear in the source code, their syntax is otherwise the same. It is
a function expression when it appears where an expression is expected, e.g. within the grouping operator or an assignment expression (as in your code)
a function declaration when it appears directly in the body of a function, module, script (global code), or eval code. Since ES6, declarations can also appear as part of a StatementList, i.e. inside a block.
a function statement when it appears where a statement is expected. Until ES6, this term was used to distinguish it from a declaration when the function syntax appeared in a block. If not inside a block, it is basically equivalent to a declaration.
Also read http://kangax.github.io/nfe/ which explain all these terms (pre-ES6 though).
For the difference between their evaluations see var functionName = function() {} vs function functionName() {}.
We can readily determine that this is not function declaration,
according to ES5 section 14:
Program :
SourceElementsopt
SourceElements :
SourceElement
SourceElements SourceElement
SourceElement :
Statement
FunctionDeclaration
A FunctionDeclaration can only be a SourceElement (a quick search for FunctionDeclaration shows no other grammatical use), and a SourceElement can only be a top-level component of a list of SourceElements (either a Program or a FunctionBody). This use of function is nested inside of an assignment, so it cannot be a top-level SourceElement.
Furthermore, we can also rule out this as a FunctionDeclaration by its definition:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }
Your code does not have an Identifier, which is mandatory for FunctionDefinitions (but optional for FunctionExpressions).
A Function Expression defines a function but does not declare a function. As such the code
var foo = function() {};
defines a function and then assigns it to a variable.
Where as
function foo() {};
defines a function and declares it without the need for an assignment.
In JavaScript there are both Object literals and function literals.
Object literal:
myObject = {myprop:"myValue"}
Function literal:
myFunction = function() {
alert("hello world");
}
What is the significance of the word literal? Can we say Java has method literals?
public void myMethod() {
System.out.println("are my literal");
}
The biggest difference is how/when it is parsed and used.
Take your exemple,
myFunction = function() {
alert("hello world");
}
You can only run myFunction() after the code got to there, since you declare a variable with an anonymous function.
If you use the other way,
function myFunction(){
alert("hello world");
}
This function is declared at compile time and can be used anytime in the scope.
Please refer to this question also.
Add-on:
A function literal in JavaScript is a synonym for a function expression.
Parallel to function expressions, function literals can have an optional identifier (name).
So if we say function expressions / function literals, it includes function expressions / function literals without an identifier (also called anonymous functions), but also function expressions / function literals with an identifier. Even if in a lot of books function expression / function literal is used as a synonym for function expression / function literal without an identifier (anonymous functions).
Function Literal
Function objects are created with function literals:
// Create a variable called add and store a function // in it that
adds two numbers.
> var add = function (a, b) {
> return a + b; };
A function literal has four parts.
The first part is the reserved word function.
The optional second part is the function's name. The function can use
its name to call itself recursively. The name can also be used by
debuggers and development tools to identify the function. If a
function is not given a name, as shown in the previous example, it is
said to be anonymous.
The third part is the set of parameters of the function, wrapped in
parentheses. Within the parentheses is a set of zero or more parameter
names, separated by commas. These names will be defined as variables
in the function. Unlike ordinary variables, instead of being
initialized to undefined, they will be initialized to the arguments
supplied when the function is invoked.
The fourth part is a set of statements wrapped in curly braces. These
statements are the body of the function. They are executed when the
function is invoked.
A function literal can appear anywhere that an expression can
appear...
source: JavaScript: The Good Parts - Douglas Crockford
That means:
myFunction = function () {
alert("hello world");
};
is a function expression / function literal, but also:
myFunction = function myFunction() {
alert("hello world");
};
is a function expression / function literal.
Don't compare JavaScript with Java, they have about as much in common as a bear and a whale. Java is an object oriented programming language, whereas JavaScript is a functional programming language.
With a functional language comes the notion of functions as first class objects: functions can be assigned to variables, can be passed as arguments as they can be the return value of other functions.
An object literal is an object you create on-the-fly and in-line. Same applies for a function literal. But the example you're giving is actually similar to a regular function declaration:
function foo()
{
alert('bar');
}
Is moved to the top of the scope, where it is converted to:
var foo = function()
{
alert('bar');
};
Makes sense, when functions can be passed as arguments/return values:
var processed = (function(someFunc)//<-- argument name
{
return function()
{
alert('I\'ll call some function in 2 seconds, get ready');
setTimeout(someFunc,2000);//<-- passes a reference to foo, as an argument to setTimeout
}
})(foo);//pass reference to function object foo here
This is only the beginning of all sorts of things you can do with JS, provided you stop treating it as a subset of Java....
A function literal is just an expression that defines an unnamed function.
The syntax for a function literal is much like that of the function statement, except that it is used as an expression rather than as a statement and no function name is required.
So When you give the method name then it can't be a method literal.
No official definition found in ECMA-262.
But according to wikipedia and many other PLs I've learnt, literals are expressions of values.
That means:
function() {alert("hello world")}
is a literal, while:
function hello_world() {alert("hello world")}
is not. Because the latter expresses not only a value, but a reference.
I upvoted vsenol's answer, but now I think it is wrong.
A function literal is not a function, but is what denotes a value of function.
For an assembly language programmer, it's something like a block of code that's stored in the .text area of memory.
Then people would want to ask what a function really is.
A function is actually a pointer or a reference to a value of function represented by a function literal as in any programming language.
For example,
public void myMethod() {
System.out.println("are my literal");
}
If we had myMethod which is a method,
{
System.out.println("are my literal");
}
then this would be the method literal, which Java does not support.
Can someone please explain the difference between the following function definitions?
var alertMessage = function alertMessage(message) {
alert(message);
}
var alertMessage = function(message) {
alert(message);
}
What are the implications of each? Thanks!
Both are function expressions, basically the difference is that the first is named, and the second one is anonymous.
For example:
var test = function test(message) {
alert(message);
};
var test1 = function(message) {
alert(message);
};
test.name; // "test"
test1.name // "" or "anonymous"
Note: The name property of function objects exist on some implementations, but it's non-standard.
Also, the name of function expressions it's useful for debugging, as you can inspect the call stack to see where you are.
This identifier is only accessible from inside the FunctionBody itself:
(function foo(){
typeof foo; // "function"
})();
typeof foo; // "undefined"
However there is a bug on the JScript implementation (in all versions of IE), which this name is leaked to its enclosing scope.
Both definitions are function expressions, as opposed to function declarations, or functions created by the Function constructor. They both assign a function to the variable alertMessage. The difference is that the first function is named, while the second is anonymous.
Named functions are usually used in function declarations, eg
function alertMessage(message) { ... }
In that case, the function declaration creates a variable in the current scope called alertMessage that references that function. Function declarations are hoisted to the top of the current scope, so you can call declared functions before they're defined in you js file.
A named function used in a function expression (such as the original question) does not create this variable, or get hoisted to the top of the execution scope, so by convention most function expressions are anonymous. The only benefits to naming a function expression are that the name variable is bound within the function (although as CMS mentions, this is implementation dependent) and the function name is output from the function's toString method. This can be useful during debugging (rather than having Firebug output (?) for a huge list of anonymous function calls).
Much more detail at MDC