Let's have, for example, a Dog
class:
class Dog {
static food;
private static static_var = 123;
constructor(private name) {}
speak() {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
}
}
Compiled to JS:
var Dog = (function () {
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
return Dog;
})();
This works equally well and is less complicated:
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
Is there any (other than "aesthetic") reason for using the anonymous function wrapper?
The advantage of an anonymous function is that it does not have to be stored in a separate file. This can greatly simplify programs, as often calculations are very simple and the use of anonymous functions reduces the number of code files necessary for a program.
The purpose of wrapping is to a namespace and control the visibility of member functions. It wraps the code inside a function scope and decreases clashing with other libraries. This is what we call Immediately Invoked Function Expression (IIFE) or Self Executing Anonymous Function.
Recursion. You can call the same function from within itself in TypeScript. This is called recursion. All recursive functions must have an end condition, which is called the base case, so that it knows when it stops executing.
An anonymous function in javascript is not accessible after its initial creation. Therefore, we need to assign it to a variable, so that we can use its value later. They are always invoked (called) using the variable name. Also, we create anonymous functions in JavaScript, where we want to use functions as values.
The main difference between the two has to do with hoisting.
TypeScript compiles the class into an assignment of a function expression to a variable. That means the resulting constructor only starts to exist at the point of assignment. In the code that occurs before, Dog
will be bound to undefined
.
On the other hand, your implementation uses a plain function that is subject to hoisting -- any code in that scope, including code that occurs before the function, can invoke the Dog
constructor.
I guess TypeScript prefers to ensure that a class does not exist before it is actually defined, possibly to allow redefining the class at several points in the same scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With