Reputation:
Edited: The expression function foo() {return 20;}, foo()
was meant to be a single argument to console.log
).
This:
console.log((function foo() {return 20;}, foo()));
Doesn't work, I get ReferenceError
because foo
has not been defined.
Why?
Upvotes: 4
Views: 154
Reputation: 21931
console.log(function foo() {return 20;}, foo());
In this code, you are passing a named (foo
) function as an argument to console.log
. Got it? You've never declared function foo
, you're just passing it as an argument. In javascript a function declaration and a function expression has the same syntax hence the confusion.
That said, passing a named (instead of anonymous) function is almost always useless. Your code is equivalent to this:
console.log(function () {return 20;}, foo());
where function () {return 20;}
is an anonymous function in contrast to a named one. And anonymous functions are very wide-spread in JS, because again, names in named function expressions are mostly useless.
Upvotes: 9
Reputation: 12419
UPDATE
I see that you edited the original question. Since you are actually passing only one argument to console.log()
, I believe in this case the reason that you're getting a ReferenceError is because when you use a comma like that, that function syntax is treated as a function expression rather than a function declaration. So it's a named function, but it's not a declared function and is still out-of-scope for the foo()
expression.
For more on declarations and statements vs. expressions, see http://2ality.com/2012/09/expressions-vs-statements.html, particularly the section "Function expression versus function declaration".
To be clear, this (on its own line) would be a function declaration:
function foo() {return 20;})
Whereas this is defining a variable and assigning it to a named function expression:
const foo = function foo() {return 20;})
In your code, you're actually creating a function expression even though it may look like it's a function declaration.
Functions can be defined anywhere that a statement or expression is allowed. So the syntax of your code is valid, but it doesn't work because expressions are scoped to where they are defined. In this case, the second argument has no access to the foo
function in the first argument. It's similar to how when using let
or const
, the variable is inaccessible outside of its block, e.g.:
if (someCondition) {
const foo = () => 20
console.log(foo()) // works
}
console.log(foo()) // doesn't work: Uncaught ReferenceError: someCondition is not defined
So if you need to call a function in an argument to console.log()
, then you need to declare the outside the console.log()
statement, for example:
function foo() {return 20;}
console.log(foo());
Alternatively, as some others have mentioned, you could use an IIFE (immediately invoked function expression), because that doesn't try to access the function from the second argument position of console.log()
(it only involves one argument):
console.log((function foo() {return 20;})())
...but in practice this is a poor use of an IIFE; there's no point in doing that here.
Upvotes: 3
Reputation: 4008
Each "log" using console.log
will output the value registered in the scope of which console.log
is called.
In your case, you are defining a function inside the call of the console.log
, this named function will only be defined in there. You'll need to define your function outside of the console.log
so you can output its value.
The second parameter will behave like the first one, and will search for a value in the global scope. It has no way to look for the value defined in the first parameter.
Upvotes: 2