51

Many programming languages require a special user-written function that marks the begin of the execution. For example, in C this function must always have the name main(). In JavaScript, however, such a function is not required.

What are the logical reason for the absence of such a dedicated top level function in JavaScript? I know this is some kind of theoretical question, but I cannot find an answer online.

unwind
  • 391,730
  • 64
  • 469
  • 606
Michele Palmia
  • 2,402
  • 2
  • 25
  • 28

5 Answers5

63

Because the entire code block is effectively one big main. In JavaScript, global code can have all of the constructs function code can have, and has stepwise execution, just like functions do. In fact, when the JS engine processes the code block as a whole, it does very nearly the same things that it does when processing a function call. See the specification's sections 10.4.1 ("Entering Global Code") and 10.4.3 ("Entering Function Code") and note how similar they are.

C doesn't allow stepwise code at the global level (you can have all sorts of initializers, and they can get kind of stepwise, but that's a different topic). And so C needs an explicit entry point (main). In JavaScript, the entry point is the beginning of the code.


Regarding your question below about whether global code is sequential. The answer is yes, it's exactly like code in a function that way. So:

var x, y, z;
x = 1;
y = 2;
z = x + y;
alert("z is " + z);

...will alert "z is 3". The code runs sequentially, top to bottom.

There are a couple of things that happen before the stepwise code is executed, though, which is useful to know. The most significant is that any declarations in the source text of the scope being entered are processed before the stepwise code begins. JavaScript has two main types of declarations: Variable declarations, and function declarations:

  1. The name of any variable declared with var is added to the scope (with the value undefined) before any stepwise code is executed. (More: Poor, misunderstood var)

  2. Function declarations are processed and the function names added to the scope before any stepwise code is executed. (JavaScript also has something else, called a function expression, which is stepwise code. More on that below.)

So for instance, in this source text:

var x;
x = 1;
foo();

function foo() {
}

the declarations are

var x;
function foo() {
}

and the stepwise code is

x = 1;
foo();

The declarations are processed first. This is why the call to foo works. (These same rules apply to the source text within functions.) This processing of declarations before anything else is sometimes called "hoisting," because the declarations are in a sense lifted from their location in the source text and moved to the very beginning. I prefer to think of it as two passes through the source: The first pass does declarations, the second executes stepwise code.

(Side note: Declaring a variable more than once in the same scope is perfectly legal [though pointless]. Declaring two functions with the same name is also legal; the latter declaration overrides the earlier one.)

(Side note 2: ES2015 [ES6] introduced let and const variable declarations, which behave somewhat differently from var. You can't declare a variable twice with them, they have block scope, and you can't use the variable prior to the statement where it's declared. So they're mostly not hoisted [there is something slightly like hoisting in that they prevent access to a shadowed variable in a containing scope even before the let x or whatever line].)


More detail, and possibly getting a bit technical:

var

If var happens before the stepwise code is run, you may be wondering about this:

var x = 1;

Does that happen before stepwise code, or as part of it? The answer is that in reality, that's just shorthand for two very different things:

var x;
x = 1;

The var x; part happens before the stepwise code, the x = 1; part is stepwise code and is executed when we reach it in the sequence. So:

alert(x); // "undefined" -- there **is** a variable `x`; it has the value `undefined`
var x = 1;
alert(x); // "1" -- now `x` has the value `1`

Function declarations

JavaScript has two different, but very similar-looking, things: Function declarations, and function expressions. You can tell which is which by whether you're using the resulting function as part of the expression in which it's defined.

Here's a function declaration:

function foo() {
}

These are all function expressions (we use the resulting function value as part of the expression; in computer science terminology, the function is used as a right-hand value):

// 1: Assigning the result to something
var x = function() {
};

// 2: Passing the result into a function
bar(function() {
});

// 3: Calling the function immediately
(function(){
})();

// 4: Also calling the function immediately (parens at end are different)
(function(){
}());

// 5: Also calling the function immediately
!function(){
}();

// 6: Syntax error, the parser needs *something* (parens, an operator like ! or
// + or -, whatever) to know that the `function` keyword is starting an *expression*,
// because otherwise it starts a *declaration* and the parens at the end don't make
// any sense (and function declarations are required to have names).
function(){
}();

The rule is that function declarations are processed before the stepwise code begins. Function expressions, like all other expressions, are processed where they're encountered.

One final side note: This is a named function expression:

var f = function foo() {
};

We use it as a right-hand value, so we know it's an expression; but it has a name like function declarations do. This is perfectly valid and legal JavaScript, and what it's meant to do is create a function with a proper name (foo) as part of the stepwise code. The name of the function is not added to the scope (as it would be if it were a function declaration).

However, you won't see named function expressions in very many places, because JScript (Microsoft's JavaScript engine) gets them horribly and utterly wrong, creating two separate functions at two different times.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Does this also mean that the execution of global code is **sequential**? Naturally, code inside functions is not executed unless the function is called and asynchronous code is called asynchronously (!!). But is a JavaScript program executed sequentially from top to bottom? – Michele Palmia Jan 26 '12 at 09:40
  • 2
    @Boanerghes: Yes, "stepwise" code is sequential. I've expanded the answer to address that (er, fairly thoroughly). – T.J. Crowder Jan 26 '12 at 11:11
  • When would you EVER want a named function expression? – mplungjan Jul 30 '17 at 05:29
  • 2
    @mplungjan: 1. Recursion. 2. It used to be important for debugging (certainly back in 2012 when the above was written), so your functions had names in stack traces and such. That's less of an issue now thanks to ES5's method syntax in object initializers, ES2015's inferred function names, and modern devtools that go beyond the rules of inferred function names. – T.J. Crowder Jul 30 '17 at 09:16
  • 2: `bar(function() { })` passes a function statement in, not the function statement's result, no? – Ask P Jan 18 '20 at 12:22
5

JavaScript is event-driven, the program written in JavaScript doesn't have a start and an end. You can compare it to any desktop UI toolkit, where you handle button clicks and key presses, but there is no obvious main once the program is initialized.

For instance there is a window.onload event that is triggered when the page is loaded - and which you can handle.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 3
    That's not strictly true. JavaScript does have a start and an end in many environments. The only time it is kept alive is when used in the browser. Additionally, events like `window.onload` aren't part of JavaScript, they're part of DOM. – Andy E Jan 26 '12 at 09:11
  • 7
    **JavaScript**, itself, is not inherently event-driven. JavaScript on browsers, and in environments like NodeJS, is event-driven, but note that the *language* is something in and of itself, independent of the environments. – T.J. Crowder Jan 26 '12 at 09:12
  • @AndyE: True, I actually upvoted *thg435*'s answer to put my own lower. – Tomasz Nurkiewicz Jan 26 '12 at 09:13
5

in a scripting language, the code is executed from the first line in the file to the end as if it was being typed into an interpreter. (this doesn't preclude parsing and compiling the code as long as those process don't effect the denotational semantics described.)

Dan D.
  • 73,243
  • 15
  • 104
  • 123
0

Javascript,python and PHP there are scripting language. These programming languages are not using main() function.

  • technically, python _can_ have a [main](https://stackoverflow.com/questions/419163/what-does-if-name-main-do-in-python) function/block – Suraj Rao Nov 09 '22 at 05:16
-6

You already know the answer

In JavaScript, however, such a function is not required!

JavaScript is scripting language while C needs to be compiled.

CAGE
  • 11
  • 11
    Your rationale is wrong. There is no reason why a compiled language would need an explicit entry point any more than a scripting language. In fact, there exist compiled languages without explicit entry point and scripting languages without one. Also, the distinction isn’t even meaningful since most modern JavaScript execution engines *do* compile the code before execution (and there are C code *interpreters*). – Konrad Rudolph Jan 26 '12 at 10:27