I read in a book about function declaration. The code goes like this.
function outer(){
assert(typeof inner === "function", "inner() in scope before declaration");
function inner(){}
assert(typeof inner === "function", "inner() in scope after declaration");
assert(typeof window.inner === "undefined", "inner() undefined in global space")
}
When the tests are run all the three statements are asserted true, showing that the inner() function existed in scope before its declaration. My concept about javascript is that the script is executed line by line and the functions should be declared before there call.
The question is how can the inner function exist in the scope before its declaration?
My concept about javascript is that the script is executed line by line and the functions should be declared before there call.
That's incorrect. In JavaScript, all function declarations in an execution context are processed upon entry into that execution context, before any step-by-step code is executed. So function declarations within functions are processed upon entry into the function when it gets called, and function declarations at global scope are processed before any global step-by-step code is executed. This is sometimes called "hoisting" (because the function declarations are effectively "hoisted" [lifted] up to the top of the scope they're declared in). (Side note: var is also hoisted, more on my blog: Poor misunderstood var.)
This is distinct from function expressions, which like all expressions, are evaluated in the step-by-step execution of the code.
Here's a function declaration:
function foo() { }
Here are three function expressions, note that in each case, they're used as right-hand values (e.g., they're assigned to a var or property, passed into a function, used in a containing expression, etc.), which is what makes them expressions rather than declarations:
var x = function foo() { };
obj = {
b: function bar() { }
};
doSomethingWith(function() { });
There I've shown two named function expressions and one anonymous function expression. If you're going to be writing code for IE8 and earlier, you may want to steer clear of named function expressions as IE's "JScript" interpreter gets them wrong; more (also my blog): Double take.
Javascript executes a function in two Pass, consider this :
There are two ways that you can use a function
1st: function quack(num){
for(var i=0; i<num ; i++)
{
console.log("quacking")
}
} - this is a function declaration.
2nd: var fly = function(num){
for(var i=0; i<num ; i++)
{
console.log("Flying!!!")
}
} - This is a function expression.
Now in the first pass the javascript looks for function declaration
which is
function quack(num){
for(var i=0; i<num ; i++)
{
console.log("quacking")
}
}
So it assigns quack's reference to a variable
which has the same name as that of the method ie.. quack .
So if you call quack() before you declare it, it works fine.
However in the 2nd pass it looks for function expression which
means you cannot call fly before evaluating it.
I hope this gives a better explanation.
Related
How the variable 'str2' is available inside the callback method passed to display method?
str2 should be visible only inside function 'name'.
a = {
display: function (n){
console.log("I am inside display method");
n();
}
}
function name(a,str2)
{
a.display(function (){
console.log(str2);
})
}
name(a, 'ddd');
Variable scoping in Javascript is hierarchical. Lower scopes have access to all variables of all higher scopes. Here's an example:
function outer() {
var foo = 2;
function inner() {
console.log(foo); // 2
}
}
It doesn't matter if a variable is passed as a parameter or if it was defined as a local var.
Yes str should be visible only inside function 'name' yes it is working same you said, in JavaScript function declarations loads before any code is executed, and scope depend on execution context
in your code scope of str2 is inside name() function and you call a.display() within this scope (within scope of name()) that's why str2 available inside display() at the time of execution.
To evaluate name(a, 'ddd'), the compiler will create a new stack frame and place two slots on it, one a, which will be a reference to the global object of the same name, and str2, which will contain the string literal 'ddd'. Then the body will be evaluated.
In the body, to evaluate a.display(function(){...}), the value of a.display will be resolved to the function with parameter n. To evaluate n(function(){...}), a new stack frame will be created with n assigned to the closure that results from evaluating the anonymous callback (a closure being a combination of a pointer to the static scope of the function and the compiler generated code for the function itself). Then the body of the a.display function will be evaluated.
In the body, the console.log will be called with the given string. Then the callback n() will be evaluated. Since n doesn't take any parameters, it will just be evaluated in the topmost stack frame, so when the time comes to evaluate console.log(str2), str will not be found on the current stack frame, so the compiler will follow the scope chain all the way to the frame where we bound 'ddd' to str and a to the function.
That's a pretty long answer to your simple question. I'll try to shorten it later. Also, corrections are welcome, as I'm being very hand-wavy with the evaluation process.
In Javascript the variable declared on a certain scope is available in every inner scope. In this case it's a concept called "closure". This answer might give you good insight about scoping in Javascript: What is the scope of variables in JavaScript?
Hope this simple example can help you understand its usefulness:
function counter () {
var votes = 0;
this.upvote = function() { votes++; }
this.downvote = function() { votes--; }
this.getValue = function() { return votes; }
}
var counter1 = new counter();
counter1.upvote();
console.log(counter1.getValue()) // Prints 1
counter1.upvote();
counter1.upvote();
console.log(counter1.getValue()) // Prints 3
In a comment on another thread I started, someone said this:
#adlwalrus yes. try this: var foo = function bar(){}; console.log(foo); But be aware that bar is only function name (what does it mean I'm not sure exactly myself) and not a reference to it, so you can't call it by doing bar(). And assigning (even named function) is not the same as declaring a function. Hoisting (bumping to top of the scope) only works for declarations, assignment will stay in place. – valentinas 6 hours ago
What purpose does a function name serve if you can't call it with bar()?
For the function to call itself.
var x = function y(val){
if (val){
console.log(val);
y(val-1);
}
};
x(5);
> 3
> 2
> 1
y(3);
> ReferenceError: y is not defined
You're referring to a named function expression. The spec requires that the name of such functions only be available within the scope of the new function. Spec quote:
The Identifier in a FunctionExpression can be referenced from inside
the FunctionExpression's FunctionBody to allow the function to call
itself recursively. However, unlike in a FunctionDeclaration, the
Identifier in a FunctionExpression cannot be referenced from and does
not affect the scope enclosing the FunctionExpression.
On the other hand, the result of that expression is a reference to the new function, which can be saved and referenced anywhere.
Lots of details here:
http://kangax.github.com/nfe/#named-expr
I'd read the whole thing.
As for benefits, another is that it makes them easier to identify in a debugger.
There are two ways to create a function in JavaScript, a "function declaration" and a "function expression." I believe it was Doug Crockford who explained it best when he pointed out that unless "function" is the very first set of characters on a given line, you're performing a function expression (not a declaration).
Function declarations are finicky creatures. You'll recognize them when you see them. They look like this:
function foo() { /* ... */ }
They're always given a name (it's requited) and the name is locally scoped to the lexical context under which the function is declared. So if you perform a function declaration in the global context, then the function can be referenced via it's name globally. If you do it within a function, the function's name can be referenced only within that function and any functions declared within that function.
I think the most important aspect of this method of declaring a function (one that is rarely commented on) is that the function initialization gets hoisted to the top of the current lexical context. Therefore, you should never, ever use a function declaration within a conditional, such as this:
//DON'T DO THIS!
if (x) {
function foo() { return 1; }
} else {
function foo() { return 2; }
}
foo(); //will always be 2, regardless of the value of x.
A function expression is slightly different. Often, they're directly assigned to a variable, like so:
var foo = function() { /* ... */ };
This is nearly identical to the function declaration above except that the initialization is not hoisted. So you can do the following:
var foo;
if (x) {
foo = function() { return 1; };
} else {
foo = function() { return 2; };
}
foo(); //will be 1 or 2, depending on the truthy-ness of x.
So, back to the original question. Function expressions can also have a name, though it's not required and it's not scoped to the context in which the function is declared (as with function declarations). Instead, it gets scoped to the function's own lexical context. This is very useful in some cases. My personal favorite is this pattern:
(function foo() {
//Do something.
setTimeout(foo, 1000);
}());
foo; //undefined
Because of the parenthesis before the word "function", this is a function expression and the name is scoped internally only. But that's okay, because we only need to call it internally (via setTimeout()). The result is that the function will execute once immediately, then will re-execute every second or so after it's finishes execution. This is safer than using setInterval() because it will wait until it's done executing before rescheduling itself, preventing overlaps that could cause missed executions and/or "domination" of the JavaScript thread.
Essentially, the use of a named function expression is limited, but when you need it, it's very powerful.
This isn't actually a specific issue I have but something I'd like to educate myself on:
As far as I understand, in JavaScript the following code
if (true) {
function greet(){ alert("Hello!"); }
} else {
function greet(){ alert("Hi!"); }
}
greet();
outputs Hi! because the code is actually evaluated as something like this:
greet = function(){ alert("Hello!"); }
greet = function(){ alert("Hi!"); }
if(true){
// possibly a no-op assignment, such as greet = greet?
}else{
// same as the other branch?
}
greet();
From a language design perspective, why does JavaScript behave in this way?
Named functions are created before the code starts, so that you don't have to put the declaration of a function before the code that uses it:
x(); // this is possible because the function already exists
function x() {}
It doesn't matter where the function declaration is, even if it's inside a flow control structure, it's still created before the code starts. So, there is no executable code at all inside the if statement in your example, not even a no-op assignment.
If you want to assign function declarations dynamically, you have use a variable:
var greet;
if (true) {
greet = function(){ alert("Hello!"); }
} else {
greet = function(){ alert("Hi!"); }
}
greet();
You don't have to use anonymous functions though, you could assign one of two named functions to the variable.
You may have found a quirk of the language and if you look a bit further you will also find different implementations.
ECMAScript processing has two phases - in the first, all declarations are processed to create named properties within the scope of their declaration. In the second, the code is executed. So declared functions and variables are available in their declared scope from the start of execution, regardless of where in the code they are declared.
And those that are created or assigned values by assignment will have values only when the assignment code is executed.
So:
// Call x
x();
// Declare x
function x(){}
works without error. This is colloquially called "hoisting", meaning declarations are "hoisted" to the top of the scope.
However, to paraphrase your example:
if (true) {
function x(){
alert('true x');
}
} else {
function x(){
alert('false x');
}
}
// In most browsers
x(); // false x
// But in Firefox
x(); // true x
For most browsers, the second declaration overrides the first. That is because ECMAScript does not have block scope, only function and global scope.
However, in this case extensions are allowed to the language. Firefox treats the above as named function expressions, hence is shows true x. More importantly, because other browsers treat the expressions as declarations, x can be called from above the code block but in Firefox it can't, you'll get an error.
The bottom line is if you want to conditionally assign a function to a named parameter or variable, do it explicitly like:
var x;
if (true) {
x = function (){
alert('true x');
};
} else {
x = function (){
alert('false x');
};
}
so that you get consistent behaviour. And you must also remember that x will not be a function until after the code has been executed, it will not be "hoisted" because it isn't a declaration.
First, it does not always behave in this way. In the case of Function Expressions function object is only available in the internal scope.
Second, when you define a function it is very likely that you want to use it in the current scope. So it is very natural that it will become available in the current scope. Consider that the enclosing scope (depending on the function definition location) is the global object or the enclosing function body not the if block.
Now, I can reduce your question to the following question:
Why the function name is used as the variable name?
A : Otherwise developers have to always assign function to a variable (which I prefer).
My question is based on the example from a book "Object Oriented JavaScript" (page 81 - Lexical Scope)
So, i understand from this example ...
function f1(){var a = 1; f2();}
function f2(){return a;}
f1();
... that:
a is not defined
But, how f1 get's to know about f2, which is defined after f1 ?
This behavior raises a question:
How JavaScript interpreter works ?
I assume, that it:
scans the code and simply stores the functions, not assigned to any var, in a global environment
Invokes a function in ad-hoc way: when there is no such a function in a global environment, then complain.
Function declarations are processed upon entry into an executable context (e.g., the global context, or a function call), prior to any of the step-by-step code in the context being processed.
So in your code, these things happen (in this order):
A "variable object" is created for the execution context.
Entries (actually, literally, properties) on the "variable object" are created for every var and function declaration in the context (plus a few other things). In your case, that's f1 and f2. Initially the properties have the value undefined.
All function declarations are processed, and so:
The f1 function is defined and assigned to its property on the variable object.
The f2 function is defined and assigned to its property on the variable object.
The f1(); line is executed, calling the f1 function.
The f1 code refers to f2, which it gets from the variable object, and so it's what we expect it to be (a reference to the f2 function).
The more interesting version is this:
f1();
function f1(){var a = 1; f2();}
function f2(){return a;}
...which happens in exactly the same order listed above, because both of the declarations are handled before the first line of step-by-step code.
Function declarations are different from function expressions, which just like any other expression are evaluated when they're reached in the step-by-step execution of the code. A function expression is any time you create a function and use it as a right-hand value, e.g., assign the result to a variable or pass it into another function. Like this:
var f2 = function() {
};
or this
setTimeout(function() {
alert("Hi there");
}, 1000);
Note that we're using the result of the function statement as the right-hand value (in an assignment, or by passing it into a function). Those are not pre-processed upon entry into an execution context (e.g., not at Step 3 above), they're handled when the flow of code reaches them. Which leads to:
f1();
function f1(){var a = 1; f2();}
var f2 = function(){return a;};
...which fails, because f2 is undefined as of when it's called.
You can use a declared function's value as a right-hand value without turning it into a function expression (we do that all the time), so long as you do it in two separate statements. So:
alert("Beginning");
function foo() { ... }
setTimeout(foo, 100);
That happens in this order:
foo is created (since it's defined by a declaration).
The alert runs.
The setTimeout runs.
(Later) foo is called.
One last point: Although they should work, a function expression that includes a function name does not work reliably on all implementations and must, for now, be avoided:
var f = function foo() { ... }; // <== DON'T DO THIS
Or
setTimeout(function foo() { // <== DON'T DO THIS
}, 1000);
Internet Explorer, in particular, has issues with those, and other implementations have at various times as well.
More to explore:
Poor misunderstood var
Closures are not complicated (because it talks about variable objects and how symbols are resolved)
Anonymouses anonymous (talks more about named function expressions)
you don't have access to variable 'a' inside function f1, because function f2 is not defined inside f1 scope
if you define f2 inside f1:
function f1(){function f2(){return a;} var a = 1; f2();}
f1();
you don't have any problems
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