Hands-On Functional Programming with TypeScript
上QQ阅读APP看书,第一时间看更新

Function declarations and function expressions

In the preceding section, we introduced the possibility of declaring functions with (a named function) or without (an unnamed or anonymous function) explicitly indicating their name, but we didn't mention that we were also using two different types of function.

In the following example, the named function, greetNamed, is a function declaration while greetUnnamed is a function expression. For the time being, please ignore the first two lines, which contain two console.log statements:

console.log(greetNamed("John")); // OK
console.log(greetUnnamed("John")); // Error

function greetNamed(name: string): string {
return 'Hi! ${name}';
}

let greetUnnamed = function(name: string): string {
return 'Hi! ${name}';
};

We might think that the preceding functions are identical, but they behave differently. The JavaScript interpreter can evaluate a function declaration as it is being parsed. On the other hand, the function expression is part of an assignment and will not be evaluated until the assignment has been completed.

The primary cause of the different behavior of these functions is a process known as variable hoisting. We will learn more about the variable hoisting process in the Function scope and hoisting section later in this chapter.

Fortunately, the TypeScript compiler can detect this error and throw a compilation-time error. However, if we compile the preceding TypeScript code snippet into JavaScript, ignore the compilation errors, and try to execute it in a web browser, we will observe that the first console.log call works. This is the case because JavaScript knows about the declaration function and can parse it before the program is executed.

However, the second alert statement will throw an exception, to indicate that greetUnnamed is not a function. The exception is thrown because the greetUnnamed assignment must be completed before the function can be evaluated.