Adam Rackis
Adam Rackis

Reputation: 83356

Why does leaving off a semicolon break this code?

Or put another way, why does semicolon insertion fail, leaving the code below broken.

function Foo() { }

Foo.prototype.bar = function () {
    console.log("bar");
} // <------------ missing semicolon

(function () {
    Foo.prototype.la = function () {
        console.log("la");
    };
})();

Why is the JavaScript parsing engine trying to combine Foo.prototype.bar = function () { with what's in my closure? Is there anything I could put in that closure that would make this sensible?

I'm not advocating leaving off semicolons with the expectation that semicolon insertion will save you; I'm just wondering why (a more useful version of) the above code broke when I accidentally left one off.

Upvotes: 4

Views: 412

Answers (2)

user1106925
user1106925

Reputation:

Think of it like this...

Foo.prototype.bar = function () { // <-- 1. function
    console.log("bar");
}(function () {    // <-- 2. call the 1. function, passing a function argument
    Foo.prototype.la = function () {
        console.log("la");
    };
})();  // <-- 3. tries to invoke the return value of the 1. function, 
       //            but "undefined" was returned.

I don't like using () for IIFE. I prefer other operators.

Foo.prototype.bar = function () {
    console.log("bar");
}

void function () {
    Foo.prototype.la = function () {
        console.log("la");
    };
}();

If we go back to the original, and have the first function return a function, you'll see that one invoked.

Foo.prototype.bar = function () { // <-- 1. function

    console.log("bar");
    return function() { alert('INVOKED'); }; // 2. return a function

}(function () {    // <-- 3. call the 1. function, passing a function argument
    Foo.prototype.la = function () {
        console.log("la");
    };
})();  // <-- 4. tries to invoke the return value of the 1. function,
       //         which will now call the returned function with the "alert()"

Updated to use a unary operator as suggested by @Lasse Reichstein, as a binary operator will still evaluate its left and right operands, and return the result, which will be used for the assignment.

Upvotes: 3

James M
James M

Reputation: 16718

Because it sees the ( on the line below and takes it to mean you want to call the above (using the below function as an argument).

Upvotes: 4

Related Questions