0

I wasn't really sure what to name this question, as that is almost the question itself. Basically I was messing with some code and found something that I can't quite explain. Here's a simplification:

function foo (a, b) {
    if (foo) {
        console.log("foo is true");
    } else if (!foo) {
        console.log("foo is false");
    } 
}

foo();

This outputs "foo is true", but what I don't understand is how is Js evaluating a function without executing it ( lack of (); ) and how can I execute it even without passing parameters defined in the function. Maybe I should say that the only language I really know is java.

Gryxs
  • 146
  • 1
  • 6
  • because a function is truthy... http://stackoverflow.com/questions/28571451/equality-of-truthy-and-falsy-values-javascript – epascarello Dec 06 '15 at 20:53
  • `foo` is the function name so by logic it's not `undefined` so it must exist (or be `true`) – Felipe Alarcon Dec 06 '15 at 20:56
  • JS does not have to evaluate/call function in your example. You can think of a function in JS as an object but with additional feature - ability to being called. Note that `if (foo)` is something different than `if (foo())` – xersiee Dec 06 '15 at 20:58
  • The function is called once (on the last line), and the function object is used twice (once in each `if` condition). – Florent Georges Dec 06 '15 at 23:54

5 Answers5

4

It's simple:

  • Functions are just objects with an internal [[Call]] method.

  • All objects produce true when coerced to booleans.

Oriol
  • 274,082
  • 63
  • 437
  • 513
1

In JavaScript, a function is a value (a somewhat special value, that you can call, using the () operator). In JavaScript, the following values are "false" when evaluated in a boolean context:

  • false
  • 0
  • ""
  • undefined
  • null
  • NaN

All other values are "true". Therefore, a function is always "true".

Florent Georges
  • 2,190
  • 1
  • 15
  • 24
  • Ok that makes perfect sense, but in that case there is absolutely no condition that would make this code run the "else if" block, right ? – Gryxs Dec 06 '15 at 21:09
  • No. Not if you test for the boolean value of a function like you do (the function object itself, not the value returned when calling it). It's always true. – Florent Georges Dec 06 '15 at 23:52
0

It is evaluating the reference to the function that the identifier foo is currently referring to. JavaScript uses object references to point to functions and variables, that you can change quite easily. This allows you to check which function you are currently referencing.

J. Murray
  • 1,460
  • 11
  • 19
0

In Java your code would not be legal because the parameter signature has to match the function's parameter signature which includes the name of the function, and its parameter list.

In Javascript the only thing that matters is the name of the function. There is NO overloading in Javascript. This makes sense because Javascript's object model is based off of string -> function/property maps. Java's object model is more complex and nuanced which is why you can do overloading.

So in short. foo() will call your function foo, with a and b being undefined. If you call it with foo(5) a would be 5, and b would be undefined. If you called it with foo(5, 1, 3) a would be 5, b would be 1 and 3 would be ignored. I would guess that you can probably get at 3rd argument using the Javascript arguments variable. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

Since a and b are undefined in your example, they evaluate to false. When you evaluate if(foo) you're passing the function object into the if() condition, and defined objects always evaluate to true. null and undefined both evaluate to false.

All falsey values in JavaScript

Community
  • 1
  • 1
Jazzepi
  • 5,259
  • 11
  • 55
  • 81
0

In javascript you're not required to pass any function arguments. When an argument is not passed the value of that argument is assumed to be undefined. It also prints "foo is true" because foo is defined as the function foo. You can see whats going on by running the following

function foo (a, b) {
    console.log(typeof a);
    console.log(typeof b);
    console.log(typeof foo);
}

foo();

//it prints:
//undefined
//undefined
//function

Basically calling foo(); is like calling foo(undefined,undefined);