Declare the Function vs Declaration - javascript

Why do people say "declare the function" when only statements with let, const, or var are declarations? I also get confused because the name of one type of function is a function declaration.

is that more clear?
const myFunction = function (a,b) { return a+b; }
console.log ( myFunction (5,10) ); // 15
console.log ( myFunction (25,30) ); // 55

TL;DR:
Javascript developers will often use the terms "function declaration" and "function definition" interchangeably. In some languages these are separate concepts (e.g. C); in Javascript they are not.
Probably when a JS developer says "declare the function" what they mean is "put the function here so you can call it over there."
...
However, so I don't get downvoted to oblivion:
Technically, in Javascript, this is a function declaration:
function foo(bar) {
// function body goes here
}
Whereas this is a function expression (and also a variable declaration):
const foo = function() {
// function body goes here
};
Both can be called in the usual way. The results are almost identical, except that the function declaration is hoisted and the const declaration is not.
See here for more on the difference:
https://medium.com/#mandeep1012/function-declarations-vs-function-expressions-b43646042052

Related

Eval function expression

While I was expecting that this code
var a = eval("function() { return 1; }");
console.log(a());
prints '1' in the console, I get a syntax error Uncaught SyntaxError: Unexpected token (. What am I doing wrong here?
I am working with a framework that allows to define javascript functions in the configuration, so I have no other choice but using eval.
The function keyword is ambiguous in Javascript: it can start a function declaration (a statement), or a function literal (an expression). When function is encountered in the statement position, the parser voluntarily prefers declaration over expression. Since eval expects a statement, this makes your code invalid -- function name is required for declarations. You can either provide a name:
eval('function foo() {...}')
or force the parser into the expression mode
foo = eval('( function () {...} )')
in which case function will be treated as a literal.
This is basically the same story as with {}, which can be either a block or an object literal. Something like eval('{1:2}') will fail for exactly the same reason (statement preferred over expression).
The problem is that you have a function declaration and that requires a name. For reference, this is a function declaration
function myFunc() { console.log("executed") } //<-- declaration
myFunc(); //<-- execution
What you expect to have is an unnamed function expression
var myFunc = function() { console.log("executed") }
//expression ^------------------------------------^
myFunc(); //<-- execution
Or for a truly unnamed function that you do not assign to a variable, you can have an IIFE
// v--------- brackets surrounding expression ---------v
( function() { console.log("executed") } )()
//expression ^------------------------------------^ ^^
//execution -------------------------------------------++
However, in JavaScript a standalone statement that starts with the function keyword will be treated as declaration and if it doesn't have a name, it is invalid.
However, you can go around that by surrounding the expression in brackets to make it acceptable for the parser.
//brackets v--------------------------v
var a = eval("( function() { return 1; } )");
// ^----------------------^ function expression
console.log(a());
You cannot mix function declaration and function expressions this way. You have to do the full declaration or expression inside the eval().
eval("function a() { return 1; }");
console.log(a());
This would work, as we give the function declaration a proper name, a, and then call the function this creates on the global scope.
eval("var a = function() { return 1; }");
console.log( a() );
This would also work, since the function expression assigning it to the variable a is now part of what gets evaluated. And we can then call the function in it's scope.
Neither of these should actually ever be used if there's alternatives.
The most common alternative is using new Function();.
var a = new Function( 'return 1;' );
console.log( a() );
This achieves the same end result and is slightly safer than using eval().
I would be surprised though if this was the only way the framework allows to define extra javascript functions. I guess that since it's in the config of something the security issues this gives are less important than if it's public code. But i would reread the docs of the framework to double check that this is the only option.
As the comments are 100% true that a function must contain a name or has to be initialised as an anonymous function, there is a solution to your problem.
If you want to create a function by text you could use the function constructor
new Function ([arg1[, arg2[, ...argN]],] functionBody)
For more information look at https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function

What is the difference between named and anonymous functions in var declaration? [duplicate]

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.

What's the purpose of "bar" in "var foo = function bar (){ ... }"?

In Douglas Crockford's book he writes a recursive function as:
var walk_the_DOM = function walk(node, func){
func(node);
node = node.firstChild;
while(node){
walk(node,func);
node = node.nextSibling;
}
}
I've never seen a function defined as var foo = function bar(){...} - I've always seen the right side of the declaration be anonymou as: var foo = function (){...}
Is the only purpose of the name walk in the right side of the declaration to shorten the calling of walk_the_DOM? They seem to become separate names for an identical function. Perhaps I've misunderstood how this snippet works.
Is there a functional reason for naming the function both in the variable declaration and the function construct?
Is there a functional reason for naming the function both in the variable declaration and the function construct?
Yes. function bar() {} causes the function's name property to be set to bar, which can be useful for, e.g., debugging in stack traces.
Regarding some of the naming confusion you alluded to, this might help:
function bar() {}
^ This is a function declaration, as it does not exist as part of an assignment expression.
var foo = function() {};
^ This is an assignment expression where the right-hand operand is a function expression, and where the function expression defines an anonymous function.
var foo = function bar() {};
^ This is an assignment expression where the right-hand operand is a function expression, and where the function expression defines a named function.
It's probably worth noting that function declarations can be referenced locally by their function name, so the following statements are roughly equivalent:
function bar() {}
var bar = function() {};
I say roughly equivalent, because the second statement still results in an anonymous function, rather than a named function. There's also a subtle difference in how function declarations get hoisted. Consider the following, for example:
function test() {
hello();
var hello = function () { console.log('hello'); };
}
test();
// > TypeError: hello is not a function
Note that hello was technically defined where we tried to invoke it (the exception is simply that it's not a function (yet)). This is due to variable hoisting. As expected, though, we haven't yet assigned our function to the hello variable. This is easier to show than to explain, really. Basically, due to hoisting, the above test example is equivalent to:
function test() {
var hello; // declared, but not assigned yet
hello();
hello = function () { console.log('hello'); }; // now the assignment happens
}
Compare that to an actual function declaration:
function test() {
hello();
function hello() { console.log('hello'); };
}
test();
// > "hello"
Notice that even though the declaration is below the invocation command, it still works, because function declarations get hoisted as a whole to the top of their scope (in this case, test).
If that's confusing, here's a more condensed description of behavior that might help: declarations get hoisted, not assignments. As long as you understand the difference between function declarations and function expressions, that's all you need to know. :)
By writing var foo = function (){...} you are declaring a variable named foo that holds an anonymous function. By writing var foo = function bar(){...} you are declaring a variable named foo that holds a named function as bar. As #jmar777 pointed out in his answer, this is useful to follow stack traces when debugging and bug fixing.

where in javascript is this kind of function assignment to variable useful?

I am reading the book. Javascript, The good parts by Douglas Crokford. There are examples provided in the book, but I am not able to understand where and how such examples could be useful in practice. I have modified the code here for simplicity.
here are two ways, I can do function assignment to a variable.
example1:
var test= function(ex) {
alert(ex);
};
test(5);
this produces alert box with value of 5
example2:
var test1 = function test2(ex) {
alert(ex);
};
test1(7); //this produces alert box with value of 7
test2(8)//this does not give a alert box
I have defined function test2 but assigned it to test1. why can't I access test2 directly by calling test2(8).
Further I do not see any big advantage in example 2 over example 1. If you there is some difference, and one of them is superior, I would like to hear that.
Thanks
var test1 = function test2(ex) {
console.log(test2);
};
Naming the function gives it the ability to reference itself from within its body.
test2 is visible only to test2 and its child scopes (functions) if any.
You're basically assigning a function with a name to test1, what's called a "named function expression". It's useful to debug your code because the name of the function will appear in the call stack trace rather than "anonymous function".
Functions in JavaScript are objects too, so the identifier for the function is test1 (the function object), but the function itself has a name of test2, so test1.name == 'test2'
The syntax you're referring to is called a named function expression. It is primarily used to support recursion in anonymous functions.
In javascript prior to ECMASCRIPT 5, there are two ways to do recursion when the function is anonymous.
Using arguments.callee:
(function(x){
alert(x);
if (x) {
arguments.callee(x-1);
}
})(10);
Using a named function expression:
(function countdown (x){
alert(x);
if (x) {
countdown(x-1);
}
})(10);
In ECMASCRIPT 5, when strict mode is enabled arguments.callee is no longer supported. Therefore, in ECMASCRIPT 5 strict mode and for future versions of javascript you should use named function expressions to write recursive anonymous function.
Additional answer:
Now you may be wondering, that's not the syntax you're asking about. That syntax looks like:
(function foo () { foo })()
and you were asking about:
var bar = function foo () { foo }
Actually, they're the same. The named function expression syntax applies to function expressions. Which is nothing more than functions declared in expression context.
In javascript, expression context is simply anywhere math is evaluated. Basically, expression context is anything between braces (), anything to the right of the = sign. And anything which needs to be evaluated by an operator.
Apart from the two forms above, the following are also valid named function expressions:
!function foo(){ foo };
0==function foo(){ foo };
0?0:function foo(){ foo };
The way you want it to behave is against the specification. Function declarations must be named, and their name represent variables in the current scope. But function expressions, when named, should not create a variable with their name. Instead, their name becomes available only inside the function.
Some old browsers (e.g. IE8) used to leak the names as variables, see Named function expressions demystified.
Your example 2 is not really an example of proper JavaScript. There are two ways to define a function:
var foo = function(x) { console.log(x); return x; }
and
function foo(x) { console.log(x); return x; }
note that in the first example you are effectively creating an anonymous function first, and then you attach a name ('foo') to that anonymous function object. In the second example, however, you are creating a named function object 'foo' right away.
Also, if you go to console and define first the test2 the way you did it, and then, after it's defined, enter the line var test1 = test2, then you will have both functions available.
You can see the explanation of the deeper technical difference here in another S/O answer, quite upvoted: var functionName = function() {} vs function functionName() {}

Are named functions preferred over anonymous functions in JavaScript? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
There are two possible methods for pulling out a function in Javascript:
var foo = function() { ... }
This is a bit contrived; another common pattern is:
var foo = {
baz: 43,
doSomething: function() {
// ...
}
}
versus
function foo() {
// ...
}
Is there an explicit reason to prefer one or the other?
It all comes down to preference to where you declare your functions; hoisting.
Function declarations and variable declarations are always moved ("hoisted") invisibly to the top of their containing scope by the JavaScript interpreter. Function parameters and language-defined names are, obviously, already there. This means that code like this:
function foo() {
bar();
var x = 1;
}
is actually interpreted like this:
function foo() {
var x;
bar();
x = 1;
}
Notice that the assignment portion of the declarations were not hoisted. Only the name is hoisted. This is not the case with function declarations, where the entire function body will be hoisted as well.
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
In this case, only the function declaration has its body hoisted to the top. The name 'foo' is hoisted, but the body is left behind, to be assigned during execution.
You can give names to functions defined in function expressions, with syntax like a function declaration. This does not make it a function declaration, and the name is not brought into scope, nor is the body hoisted.
foo(); // TypeError "foo is not a function"
bar(); // valid
baz(); // TypeError "baz is not a function"
bin(); // ReferenceError "bin is not defined"
var foo = function () {}; // anonymous function expression ('foo' gets hoisted)
function bar() {}; // function declaration ('bar' and the function body get hoisted)
var baz = function bin() {}; // named function expression (only 'baz' gets hoisted)
foo(); // valid
bar(); // valid
baz(); // valid
bin(); // ReferenceError "bin is not defined"
So, if your preference is to have functions hoist to the top use a function declaration otherwise use expression. I prefer the latter as I typically build object literals with methods as function expressions.
Named function expressions can be handy when errors are thrown. The console will tell you what the function is instead of stating anonymous aka stack trace.
You've hit on a couple different things here, but I'll try to hit your main question first.
In general....
function() { ... } is a function expression. Syntaxically this is on the same level as 2 or [4,5]. This represents a value. So doing var foo=function(){ ... } will work as planned, every time.
function foo() { ... } is a function declaration. This might seem to do the same thing as var foo=function(){...}, but there's a small caveat. As its a declaration, it works similar to the concept of variable hoisting in JS (basically, all variable declarations are done before any expressions are evaluated).
A good example is from here:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
Basically variable hoisting has brought the value up to the top, so this code is equivalent (in theory) to :
function test() {
var foo;//foo hoisted to top
var bar=function(){//this as well
alert("this will run!");
}
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
}
NB: I'd like to take this spot to say that JS interpreters have a hard time following theory, so trusting them on somewhat iffy behaviour is not recommended. Here you'll find a good example at the end of a section where theory and practice end up not working (there are also some more details on the topic of expressions vs declarations).
Fun fact: wrapping function foo() {...} in parentheses transforms it from a declaration to an expression, which can lead to some weird looking code like
(function foo() { return 1; })();// 1
foo; //ReferenceError: foo is not defined
Don't do this if you don't have a reason to, please.
Summary var foo=function(){ ... } is *sorta kinda * the same as function foo(){ ... } except that the former does what you think it does where you think it should whereas the latter does weird stuff unless you wrap it in parens, but that messes up the scope, and JS interpreters allow you to do things that are considered syntax errors in the spec so you're led to believe that wrong things are in fact right, etc....
please use function expressions( var f=function(){...} ). There's no real reason not to, especially considering you're somewhat forced to do it when you're using dot syntax.
On to the second thing you touched.....
I'm not really sure what to say, it's kinda sorta completely different from everything else about this.
var foo = {
baz: 43,
doSomething:function() {
...
}
}
this is known as object literal syntax. JSON, which is based off of this syntax, is a pretty neat way of formatting data, and this syntax in JS is often used to declare new objects, with singleton objects for example(avoiding all the mess with declaring a function and using new ). It can also be used in the same way XML is used, and is preferred by all the cool kids...
Anyways, basically object literal syntax works like this:
{ name1: val1, .... namek:valk }
This expression is an object with certain values initialised on it. so doing var obj={ name1: val1, .... namek:valk } means that :
obj.name1==val1;
obj['name1']==val1;// x['y'] is the same thing as x.y
...
obj.namek==valk;
So what does this have to do with our example? Basically your expression is often used to declare singleton objects. But it can also be used to declare an object prototype, so someone can later do var newObj=Object.create(foo) , and newObj will have foo as a prototype.
Look into prototypal inheritence in detail if you want to really get how useful it is. Douglas Crockford talks about it in detail in one of his many talks).
There are few advantages to naming functions
names for meta analysis. functionInstance.name will show you the name.
Far more importantly, the name will be printed in stack traces.
names also help write self documenting or literate code.
There is a single disadvantage to named functions expressions
IE has memory leaks for NFE
There are no disadvantages to function declarations apart from less stylistic control
Your question really comprises of two parts, as you don't necessarily have to make your functions anonymous if they are assigned to a variable or property.
Named vs anonymous?
#Raynos highlights the main points clearly. The best part about named functions is that they will show themselves in a stack trace. Even in situations where functions are being assigned to variables/properties, it's a good idea to give your functions a name just to aid with debugging, however I wouldn't say anonymous functions are evil at all. They do serve a fine purpose:
Are anonymous functions a bad practice in JavaScript?
Function declaration vs function expression?
For that part of the question I would refer you to this question as it probably covers the topic in far more depth than I can
var functionName = function() {} vs function functionName() {}

Categories