17

I was reading about the new JavaScript-like language from Microsoft called TypeScript. In the playground (example section), there is a simple class in TypeScript syntax converted to JavaScript code. Coming from a Java programming background, it was interesting for me to learn how OOP is done in JavaScript as compiled from TypeScript.

The TypeScript code:

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}   

var greeter = new Greeter("world");

var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
    alert(greeter.greet())
}

document.body.appendChild(button)

And the equivalent JavaScript code:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

The Typescript part is very similar to Java so I understand that. Now my question is why in JavaScript the body of the Greeter class is embedded in a an anonymous function() call?

Why not write it like this?

function Greeter(message) {
    this.greeting = message;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

What is the advantage/disadvantage of each method?

2
  • That JavaScript code makes no particular use of the immediately invoked anonymous function. You're right, it could be removed. Commented Oct 2, 2012 at 14:32
  • 1
    I thought it would be for private members, but... adding private doesn’t change anything. Commented Oct 2, 2012 at 14:32

6 Answers 6

15

The following is called an Immediately Invoked Function Expression:

(function(){ ... })();

It is used to keep the global scope clean. Though, in this case it isn't necessary since the return value is assigned to a variable Greeter. The only time this pattern is useful is when you want "private" static members.

E.g.:

var Greeter = (function () {
    var foo = 'foo', bar = 'bar'; /* only accessible from function's defined
                                     in the local scope ... */

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
Sign up to request clarification or add additional context in comments.

1 Comment

foo and bar will be private AND static in this case.
3

This is to allow for private members. In this example, all members are public so your two constructions are equivalent. However, if you want to provide for private members you need to hide them from the calling scope via a closure. Thus if you have a private member like so:

class Greeter {
    private greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
} 

You would probably get something like this:

var Greeter = (function () {
    var greeting="";
    function Greeter(message) {
        greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + greeting;
    };
    return Greeter;
})();

The greeting variable will be available to any function defined inside the anonymous function, but invisible everywhere else.

4 Comments

No it does not. var greeting is not created it's only used internal. I just tried that ;)
You would have thought you would get something like that, but you don't. TypeScript enforces the private modifier at compile time only, so even when you use it, it still sets this.greeting (which obviously isn't private at all - but your TypeScript won't compile if you try to access it).
ah then I would guess that there ARE some hidden properties that generated by the framework, that should not pollute the resulting object, just not private members
A lot of the frameworks definitions are just for internal checks. Like variable deceleration string or private functions. The framework checks if you used it correctly and creates the JavaScript that does not mind what you do.
3

Besides the obvious scoping/closure reasoning. Using an anonymous function that invokes itself immediately pre-loads (interprets) the class definition. This allows any JIT optimizations to be front loaded within the execution. In short, for larger more complex applications it will improve performance.

1 Comment

Could you link to a source with more information about the JIT part?
2

The anonymous function / self executing closure is usually used to encapsulate scope so that only the returned value is accessible outside of it. (or anything you attach to other objects, like window)

Comments

1

The anonymous function is probably there to prevent name collition with other parts of the code. Think of it this way, inside your anonymous function, you could even declare a variable called "$" to be whatever you want, and at the same time, be using jQuery on other parts of your code without conflict.

2 Comments

It's assigning to the same name, though.
I don't understand what you mean by that....could you elaborate a bit more on the comment?
-4

The closure is the sole mean to call the constructors with parameters:

var w = new Greeter("hello")

There are other methods but all complicated and with limitations and drawbacks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.