Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't JavaScript need a main() function?

Tags:

javascript

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.

like image 469
Michele Palmia Avatar asked Jan 26 '12 09:01

Michele Palmia


People also ask

How do you write a main function in JavaScript?

A JavaScript function can be defined using function keyword. Syntax: //defining a function function <function-name>() { // code to be executed }; //calling a function <function-name>(); The following example shows how to define and call a function in JavaScript.

Does TypeScript have main function?

TypeScript, as JavaScript, doesn't have a main function. The code is executed from top to bottom, so you can just create the function and call it at the end of the main file, after the imports.

How do functions work in JavaScript?

A JavaScript function is a block of code designed to perform a particular task. A JavaScript function is executed when "something" invokes it (calls it).

What is main function in node JS?

The main() is just a wrapper being used by Node. js and stays in the call stack as long as the main (non-callback) part of the program is running. The function gets added to the stack, then the statements inside the function get added as they are called and removed as they are executed.


1 Answers

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.

like image 83
T.J. Crowder Avatar answered Sep 23 '22 22:09

T.J. Crowder