Is function declaration without the "function myFunction() {}" syntax discouraged in javascript? [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
There are two ways to declare a function in Javascript:
Syntax 1:
function myFunction() {
// something awesome
};
Syntax 2:
var myFunction = function() {
// somtehing even more awesomer
};
It seems to me that I come across Syntax 1 a lot more in legacy code than in well written code (but that's purely empiric).
Q: Should prever a syntax over the other, and why ?

The only difference that I can think of is here:
This code does not run: http://jsfiddle.net/JdCRq/
myFunction();
var myFunction = function() {
console.log('test');
};
While this code does: http://jsfiddle.net/JdCRq/1/
myFunction();
function myFunction() {
console.log('test');
}
function blocks, in the context of the second example, seem to be declared (at least by name) before the code is actually run.

The first example is the normal way of declaring a function.
The second example is an anonymous function that is assigned to a variable. This is used when you declare a function as a member of an object, or assign it to the prototype of a class, and is sometimes also used when assigned to a regular variable when the normal way of declaring a function would suffice.
The only practical difference between the examples is that the second way is assigned at runtime. If you redefine a function, that happens when the code is parsed, so only the last one exists:
console.log(f()); // shows 2
function f() { return 1; }
console.log(f()); // shows 2
function f() { return 2; }
console.log(f()); // shows 2
(Although you normally wouldn't redefine a function like that, because it makes the code hard to follow.)
With an anonymous function, it doesn't exist until it is assigned, and if reassigned it changes to the new function:
condole.log(f); // shows undefined
var f = function(){ return 1 };
console.log(f()); // shows 1
f = function(){ return 2 };
console.log(f)); // shows 2

Declaring a function with the function declaration statement (the first way) binds the function name to the function object in such a way as to allow debuggers to show you the name in stack traces. There's really no reason to declare functions with var declarations in simple cases like this. (Sometimes, of course, it's necessary, as when you create functions with other functions.)
Syntactically, it's OK for function instantiation expressions (the second way) to also include a function name that's bound to the function. Unfortunately, some JavaScript runtimes don't handle that case properly and behave somewhat badly, so it's not a good idea.

Using both var and function can have some advantages depending on what you want to achieve, here are some examples;
var f1 = function nonUnique () {return true;},
f2 = function nonUnique () {return false;};
meaning f1.name === f2.name but f1 !== f2
function nonUnique () {return true;};
var f1 = nonUnique;
function nonUnique () {return false;}; // this line changes f1 too
var f2 = nonUnique;
means f1 === f2 and f1 will now return false.
function nonUnique () {return true;};
var f1 = nonUnique,
f2 = f1;
f1 = function nonUnique () {return false;}; // this line changes f1 but not f2
means f1 !== f2; f1 returns false but f2 will return true. nonUnique() will also give true.
This last example is useful of re-using native functions names but keeping them safe.
Also note that variables effectively don't exist before the line with var whereas function syntax will, and see this question, which your question is a duplicate of.

Related

Is a function declaration using function expression and anonymous function? [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
What is the difference between the following lines of code?
//Function declaration
function foo() { return 5; }
//Anonymous function expression
var foo = function() { return 5; }
//Named function expression
var foo = function foo() { return 5; }
Questions:
What is a named/anonymous function expression?
What is a declared function?
How do browsers deal with these constructs differently?
What do the responses to a similar question (var functionName = function() {} vs function functionName() {}) not get exactly right?
They're actually really similar. How you call them is exactly the same.The difference lies in how the browser loads them into the execution context.
Function declarations load before any code is executed.
Function expressions load only when the interpreter reaches that line of code.
So if you try to call a function expression before it's loaded, you'll get an error! If you call a function declaration instead, it'll always work, because no code can be called until all declarations are loaded.
Example: Function Expression
alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; }
Example: Function Declaration
alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; }
As for the second part of your question:
var foo = function foo() { return 5; } is really the same as the other two. It's just that this line of code used to cause an error in safari, though it no longer does.
Function Declaration
function foo() { ... }
Because of function hoisting, the function declared this way can be called both after and before the definition.
Function Expression
Named Function Expression
var foo = function bar() { ... }
Anonymous Function Expression
var foo = function() { ... }
foo() can be called only after creation.
Immediately-Invoked Function Expression (IIFE)
(function() { ... }());
Conclusion
Douglas Crockford recommends to use function expression in his «JavaScript: The Good Parts» book because it makes it clear that foo is a variable containing a function value.
Well, personally, I prefer to use Declaration unless there is a reason for Expression.
Regarding 3rd definition:
var foo = function foo() { return 5; }
Heres an example which shows how to use possibility of recursive call:
a = function b(i) {
if (i>10) {
return i;
}
else {
return b(++i);
}
}
console.log(a(5)); // outputs 11
console.log(a(10)); // outputs 11
console.log(a(11)); // outputs 11
console.log(a(15)); // outputs 15
Edit:
more interesting example with closures:
a = function(c) {
return function b(i){
if (i>c) {
return i;
}
return b(++i);
}
}
d = a(5);
console.log(d(3)); // outputs 6
console.log(d(8)); // outputs 8
The first statement depends on the context in which it is declared.
If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. Thus the function call "foo()" can be made anywhere in your javascript program.
If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()"
EDIT:
I should have also said that function statements (The first one) are parsed before function expressions (The other 2). This means that if you declare the function at the bottom of your script you will still be able to use it at the top. Function expressions only get evaluated as they are hit by the executing code.
END EDIT
Statements 2 & 3 are pretty much equivalent to each other. Again if used in the global context they will create global variables and if used within a closure will create local variables. However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. Therefore
var foo = function foo() { return 5; }
Is the same as
var foo = function fooYou() { return 5; }
Though the complete difference is more complicated, the only difference that concerns me is when the machine creates the function object. Which in the case of declarations is before any statement is executed but after a statement body is invoked (be that the global code body or a sub-function's), and in the case of expressions is when the statement it is in gets executed. Other than that for all intents and purposes browsers treat them the same.
To help you understand, take a look at this performance test which busted an assumption I had made of internally declared functions not needing to be re-created by the machine when the outer function is invoked. Kind of a shame too as I liked writing code that way.

difference in defining functions : JavaScript [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
Do we have any difference between the two mentioned function declaration in JavaScript
//Declaration 1
var foo = function(){
// code goes here
}
and
//Declaration 2
function foo(){
// same code here
}
When i tried to use foo's definition as a class to create other objects
var newObj = new foo();
The Declaration 2 worked but Declaration 1 did not allow me to create and object of this type
this is a function expression:
//Declaration 1
var foo = function(){
// code goes here
}
The func expression in this case is anonymous but assigned to a var foo.
for reference
This is a labeled function :
//Declaration 2
function foo(){
// same code here
}
There's not really any great reason to do expression to var. You
should always try to use labeled statements for constructors,so you
can identify an object's 'type' via its constructor.
people mostly use this where hoisting is needed.Hoisting simply means
calling something before it is defined.
Very very simple example:
foo(); // alerts 'hello'
function foo() {alert('hello');}
V/s
foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}
First creates a local variable that is assigned a function to. The second declaration creates a function. In first case there is no function to be used for the clients. This is why you can not create objects.
Check this fiddle. It is allowing both declaration:
//Declaration 1
var foo1 = function(){
alert('Declaration 1');
}
//Declaration 2
function foo(){
alert('Declaration 2');
}
var b= new foo1();
var a=new foo();
You can create object of function. here in your case declaration 1 consider foo is a variable so you can not create object of any variable that is why Declaration 2 worked and Declaration 1 did not allow you.
The first one creates an anonymous (nameless) function and assigns it to a variable called foo. The second one declares a function with the name foo. Usually those two forms can be used pretty interchangeable but there are still some differences. The following two are the main differences that come to my mind. The first one might be responsible for what you are experiencing:
Hoisting
In the second example, the complete function definition will be hoisted up to the top of the current scope. So when you write:
var a = new A();
function A() {}
JavaScript will interpret this as:
function A(){}
var a;
a = new A();
...and your code will work fine.
In the first example however, only the variable declaration will be hoisted up. The function body stays where it is. So this:
var a = new A();
var A = function(){};
will be interpreted as this:
var a, A;
a = new A();
A = function(){};
which will lead to an error, since A is still undefined by the time you try to create an instance.
The name property
As I said, the first one creates an anonymous function. That means, if you try to access the name property of that function it will return an empty string:
var A = function(){};
console.log(A.name) //{empty string}
In the second example, your function has the actual name A:
function A(){}
console.log(A.name) //A

Is Function Declaration is only right way to define function inside closure? [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
What is the difference between the following lines of code?
//Function declaration
function foo() { return 5; }
//Anonymous function expression
var foo = function() { return 5; }
//Named function expression
var foo = function foo() { return 5; }
Questions:
What is a named/anonymous function expression?
What is a declared function?
How do browsers deal with these constructs differently?
What do the responses to a similar question (var functionName = function() {} vs function functionName() {}) not get exactly right?
They're actually really similar. How you call them is exactly the same.The difference lies in how the browser loads them into the execution context.
Function declarations load before any code is executed.
Function expressions load only when the interpreter reaches that line of code.
So if you try to call a function expression before it's loaded, you'll get an error! If you call a function declaration instead, it'll always work, because no code can be called until all declarations are loaded.
Example: Function Expression
alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; }
Example: Function Declaration
alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; }
As for the second part of your question:
var foo = function foo() { return 5; } is really the same as the other two. It's just that this line of code used to cause an error in safari, though it no longer does.
Function Declaration
function foo() { ... }
Because of function hoisting, the function declared this way can be called both after and before the definition.
Function Expression
Named Function Expression
var foo = function bar() { ... }
Anonymous Function Expression
var foo = function() { ... }
foo() can be called only after creation.
Immediately-Invoked Function Expression (IIFE)
(function() { ... }());
Conclusion
Douglas Crockford recommends to use function expression in his «JavaScript: The Good Parts» book because it makes it clear that foo is a variable containing a function value.
Well, personally, I prefer to use Declaration unless there is a reason for Expression.
Regarding 3rd definition:
var foo = function foo() { return 5; }
Heres an example which shows how to use possibility of recursive call:
a = function b(i) {
if (i>10) {
return i;
}
else {
return b(++i);
}
}
console.log(a(5)); // outputs 11
console.log(a(10)); // outputs 11
console.log(a(11)); // outputs 11
console.log(a(15)); // outputs 15
Edit:
more interesting example with closures:
a = function(c) {
return function b(i){
if (i>c) {
return i;
}
return b(++i);
}
}
d = a(5);
console.log(d(3)); // outputs 6
console.log(d(8)); // outputs 8
The first statement depends on the context in which it is declared.
If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. Thus the function call "foo()" can be made anywhere in your javascript program.
If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()"
EDIT:
I should have also said that function statements (The first one) are parsed before function expressions (The other 2). This means that if you declare the function at the bottom of your script you will still be able to use it at the top. Function expressions only get evaluated as they are hit by the executing code.
END EDIT
Statements 2 & 3 are pretty much equivalent to each other. Again if used in the global context they will create global variables and if used within a closure will create local variables. However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. Therefore
var foo = function foo() { return 5; }
Is the same as
var foo = function fooYou() { return 5; }
Though the complete difference is more complicated, the only difference that concerns me is when the machine creates the function object. Which in the case of declarations is before any statement is executed but after a statement body is invoked (be that the global code body or a sub-function's), and in the case of expressions is when the statement it is in gets executed. Other than that for all intents and purposes browsers treat them the same.
To help you understand, take a look at this performance test which busted an assumption I had made of internally declared functions not needing to be re-created by the machine when the outer function is invoked. Kind of a shame too as I liked writing code that way.

Why doesn't this extension work?

I wanted to have a method of adding functionality to pre-existing functions, so I made this:
Function.prototype.attachFunction = function(toAttach)
{
var func = this; //This is the original function, which I want to attack toAttach function to.
//Can I do this without wrapping it in a self-executing function? What's the difference?
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
I paste this into the Google Chrome console, and there are no errors, however, it does not (or so it would seem) alter the original function at all.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f(); //Prints out just "g".
When attachFunction executes, it returns a function which executes func() and toAttach. However, if you change your code to be the following, it will attempt to execute both functions, where currently the old f is still called at the end.
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f(); //Causes an infinite loop since calling func() is the same as calling this()
To merge two functions we need to wrap them the same way but not while extending Function
var func1 = function(){
console.log('g');
};
var func2 = function(){
console.log('New function!');
};
func1 = (function(f1,f2){
return function(){
f1();
f2();
}
}(func1, func2));
func1(); //Writes out both g and New function!​​​​​​​​​​​​​​​​​​​​
The reason I pass in func1, and func2 as parameters is to prevent the same problem of getting into an infinite loop. I want to maintain a reference to these functions at that point in time.
A helper function would then be the following
function combineFunctions(f1, f2){
return function(){
f1();
f2();
}
}
and would be used like this
var f = function() {console.log("g");};
f = combineFunctions(f,function(){console.log("New function!");});
f();
The attachFunction method you've set on the Function prototype is a higher-order function, or combinator, that accepts a function and returns a new function. It is inherited by any function created thereafter, as expected. However, when it is called it does not alter the state of f in any way, it simply produces a new function that calls f, or the calling function rather.
So, if you wanted to see both console.log messages, you simple need to call the function it returns, like so:
f.attachFunction(function(){console.log("hi")})();
or more simply:
f.attachFunction(f)();
Note that although functions are objects, the execution context (code) of f is not a property of f such that it can be manipulated directly, it is kept in an internal attribute.
Underscore.js' wrap() function should be quite close to what you want.
Currently, you're trying to call a variable as if it were a function (toAttach is a variable and you're smacking some parenthesis on the far side of it). Consider this: toAttach may CONTAIN a function, but that does not make it a function (much like a grocery store is not an apple). Instead you need to call the function contained within the variable.
There are several ways to do this (although only one or two apply here), none of the [right] ways involve eval() (life lessons).
Consider this thread. Pass the function name as a string and then use
window[toAttach]();
to call the function. It's a bit hacky, and lacks the finesse of passing the function as an object, but it works.
Alternatively (completely depending on your needs) you can bind the function to an event. If you're extra sneaky (and why not?) you can use
setTimeout(toAttach, 0);
Where toAttach is a reference to the actual function (again).
Finally, and best, I believe, is the Function.call() method. Using this, you can call a function stuffed in a variable, and even pass it a context for this.
toAttach.call([Context]);
Where [Context] is the context of the function (ie, what this refers to when inside of the function, in most cases it can be left blank to get the desired scope). I can't say I've tested it under your certain circumstances (thus why I have included it last), but I believe it should give you the results you're looking for.
Here's my attempt to achieve this, it is not clean as if it was entirely in the prototype but it works. There are probably better ways than mine.
var bindings={};
function execBindings(func_name) {
if (bindings[func_name] != undefined) {
for (var i=0;i<bindings[func_name].length;i++) {
bindings[func_name][i]();
}
}
}
Function.prototype.bind=function(action){
if (bindings[this.name] == undefined) {
bindings[this.name]=[];
}
bindings[this.name].push(action);
}
Then, to use the binding :
function f() {
alert("foo");
execBindings("f");
}
f.bind(function(){
alert("bar");
});
f.bind(function(){
alert("test");
});
f();
which results in 3 alerts, in the order thwy were binded to the function.
There are two problems I just found.
problem 1.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f();
It definitely doesn't work, cause attachFunction just wrap around your original function and return the wrapped, it doesn't change the original function, which means your f function is still f = function() {console.log("g");}
Problem 2.
If you reassign f with the result of attachFunction, an Maximum call stack size exceeded will occur. In the definition of attachFunction:
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func;
The func function call himself recursively.
Update
I prefer this approach.
Function.prototype.attachFunction = function(toAttach)
{
var that = this;
func = (function()
{
return function()
{
that();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f();

Javascript Function Definition Syntax [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
Declaring functions in JavaScript
I've seen 2 different syntaxes for defining functions in javascript:
function f() {
...
}
As well as
var f = function() {
...
};
What's the difference between these? Is one of them deprecated?
Neither are deprecated, and both will work. The difference here is that one is a named function ( function f() ) while the other is a variable equal to a function ( var f = function() ).
You have to be careful when setting variables equal to functions. This will work:
var f = function(n) { console.log(n); };
f(3); // logs 3
But this will break, since the variable is defined after the call to it.
f(3); // what is f? breaks.
var f = function(n) { console.log(n); };
But normal functions work fine.
function abc(n) { console.log(n); }
abc(3); // logs 3
xyz(5); // logs 5
function xyz(n) { console.log(n); }
This is because the code is analysed before execution, and all functions are available to call. But setting a var equal to a function is like setting a var to anything else. The order of when it happens is important.
Now for some more confusing stuff...
There are also 'self-executing' anonymous functions. They go by a variety of names. The most common way to do it looks something like this:
(function() {
// code in here will execute right away
// since the () at the end executes this (function(){})
})();
There is also an arguably better version.
!function() {
// again, the tailing () will execute this
}();
Check out this Stack Overflow post for more on anonymous functions.

Categories