I use only jQuery for writing JavaScript code. One thing that confuses me is these two approaches of writing functions,
First approach
vote = function (action,feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
Second approach
function vote(action, feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
What is the difference between the two and why should one use the first approach or the second approach?
The first is a function expression assigned to the vote variable, the second is a function declaration.
The main difference is that function statements are evaluated at parse time, they are available before its declaration at runtime.
See also:
Named function expressions demystified (article)
Explain JavaScript’s encapsulated anonymous function syntax
function myFunction() {}
...is called a "function declaration".
var myFunction = function() {};
...is called a "function expression".
They're very similar; however:
The function declaration can be declared after it is referenced, whereas the function expression must be declared before it is referenced:
// OK
myFunction();
function myFunction() {}
// Error
myFunction();
var myFunction = function() {};
Since a function expression is a statement, it should be followed by a semi-colon.
See Function constructor vs. function declaration vs. function expression at the Mozilla Developer Centre for more information.
The function declaration syntax cannot be used within a block statement.
Legal:
function a() {
function b() {
}
}
Illegal:
function a() {
if (c) {
function b() {
}
}
}
You can do this though:
function a() {
var b;
if (c) {
b = function() {
};
}
}
The first one is a function expression,
var calculateSum = function(a, b) { return a + b; }
alert(calculateSum(5, 5)); // Alerts 10
The second one is a plain function declaration.
Related
can anyone explain to me what is JS doing here? Can anybody explain what is going on here in terms of type coercion, IIFE, and closures?
Function.prototype.toString = (
function() {
const toStringFnRef = Function.prototype.toString;
return function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
)();
console.log(1 + function x() { alert('hi') });
//output: "1start:function x() { alert('hi') }end"
The IIFE is being used to create a local scope where the variable toStringFnRef contains the original value of Function.prototype.toString. Then it redefines this with a function that calls the original function and wraps the result in start: and end.
This could also be done using a lexical block (in ES6 most IIFEs can be refactored like this):
{
const toStringFnRef = Function.prototype.toString;
Function.prototype.toString = function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
When you do 1 + function x() { alert('hi') } it converts both 1 and the function to strings so it can concatenate them. So this calls your redefined Function.prototype.toString(), which surrounds the normal string of the function with those wrappers. This is then concatenated with 1.
The context:
I am reading the book You Don't Know JS: Up & Going, Chapter 2: Into JavaScript. In the Polyfilling section, the author gives the following example:
if (!Number.isNaN) {
Number.isNaN = function isNaN(x) {
return x !== x;
};
}
So, what is being done here is creating a polyfill so that the ES6 method Number.isNaN can run in older browsers (ie, pre-ES6 versions). As I expected, he makes use of the older isNaN method. The former method is actually meant to deprecate the latter by design.
The question:
Why is isNaN being used as the identifier of the named function expression? I would have expected it to be used in the body somehow. Why? Because all of the identifiers usually seen in examples around the web, when comparing function expressions vs function declarations take the following form:
Function declaration:
function foo() {
// ..
}
Function expression:
var foo = function bar() {
// ..
};
So in this example bar is being defined within the brackets after the 'bar()' string. So why use 'isNaN' above when isNaN is an already defined function within JavaScript? Are we actually overwriting it for the purpose of the polyfill? What am I missing/misunderstanding here?
When you have a named function in an expression, that value is not hoisted but is saved in expression scope. So original value is not changed.
Sample
function bar(){
console.log("In Bar")
}
var foo = function bar(){
console.log("In Foo")
}
bar();
foo();
Why should you use it?
In case of exception, that will help you in debug. An anonymous function will not show any name in stack trace and if you have say 4-5 anonymous functions in 1 function, it becomes difficult as to which one failed. Having a named functions makes it little simple.
var bar = function Test() {
(function() {
(function() {
(function() {
throw new Error("I have no Name2")
})()
})()
})()
}
var foo = function Test() {
(function inFoo1() {
(function inFoo2() {
(function inFoo3() {
throw new Error("I have no Name2")
})()
})()
})();
}
function init() {
try {
foo();
} catch (ex) {
console.log(ex.stack)
}
try {
bar();
} catch (ex) {
console.log(ex.stack)
}
}
function start() {
init();
}
start();
You can also refer to Why using named function expressions? for more information.
Can anyone explain why
function x() {
console.log("Hello!");
}
var a = x;
a();
x();
produces
Hello!
Hello!
but this
var a = function x() {
console.log("Hello!");
}
a();
x();
throws an error when you try to call function x? Is the second x function not considered a hoisted function? I tried this in both nodejs and a browser.
What you have in the second example is what's called a named function expression.
Its name is not added to the containing scope, but is accessible within the scope of the function itself:
var a = function x() {
alert(x);
};
a();
This is useful in writing recursive functions or functions that otherwise reference themselves, as it ensures that the name won't get clobbered due to anything that happens outside the function's scope.
It also allows you to create self-referencing functions in places where you can't use a function declaration, such as in an object literal:
var myFavoriteFunctions = {
factorial: function f(n) {
return n === 1 ? 1 : n * f(n);
},
identity: function (v) { return v; }
};
console.log(myFavoriteFunctions.factorial(10));
Your first example is a function statement, which declares a name in its containing scope.
Your second example is a named function expression, which does not.
For more information, see here.
JavaScript allows this:
function outside() {
inside();
return 44;
function inside() {
console.log("inside");
}
}
When outside is called the output is:
inside
44
Why does this work and why doesn't it work for other statements like the one below:
function outside() {
return 44;
console.log("inside");
}
which just prints 44.
What you see is the effect of hoisting. When a function is about to be executed, all the variable and function declarations are evaluated first, before the function is really executed. Thus your first function is equivalent to
function outside() {
function inside() {
console.log("inside");
}
inside();
return 44;
}
Details can be found in the specification, 10.4.3 Entering Function Code and 10.5 Declaration Binding Instantiation.
Why does JavaScript allow function declarations after the return statement?
Why the language is defined like this can probably only be answered by Brendan Eich.
Because the file is parsed first and function definitions are read at that time. You are calling the function before you return, so that works just fine. Most programming languages allow you to define functions after calling them, because they all work in two steps: parsing and execution.
In the first case first the function inside is executed and then it comes to return..so it returns 44..
But in the second case the outside function first encounters return which means to exit from that function no matter what is return below... so it only prints 44
function outside() {
inside(); //calling inside();
return 44;
function inside() {
console.log("inside");
}
}
but here
function outside() {
return 44;
console.log("inside");
}
you are just returning not calling inside() at all.
Function declaration:
function myName() {
}
Function Expression:
var myName = function() {
};
These are very different, the function declaration (1) is defined when the Javascript is parsed, and not when it is executed. whereas the function expression (2) is defined when the Javascript is executed.
So technically it is not being defined after the return statement.
At least this is how I understand it.
So I want to call function B in function A, but function B is fully declared after function A. I know that in c++ we'd use function prototypes on B, but what about javascript?
code:
markerArray = function() {
// some code here
this.array = [];
this.clearArray = function() {
for(var i = 0; i<this.getLength(); i++)
// for loop code
}
this.getLength = function() {
return this.array.length;
}
// some code here
}
these reason why I put this.getLength below is mainly because my coding style/structure is more readable this way
Javascript doesn't care about this requirement. It will simply work as long as Function A isn't called until after the file is loaded. Function A will be defined, Function B will be defined, then Function A can be called using Function B inside of it with no problem.
Not a problem. Function declarations are hoisted to the top of the enclosing variable environment, so they do not need to be declared in order.
A();
function A() {
B();
}
function B() {
alert('B was called');
}
If you meant something else, you'll need to explain it in your question.
It depends on how you declare your functions. If you declare a function via the Function constructor or a function expression, order matters.
a(1); //this call won't work
//function expression of an anonymous function assigned to the variable multiply
var a = function(i) {
b(i);
}
// b is defined using Function constructor
var b = new Function("i","alert('B was called with ' + i)");
a(1); //this call will work