2

I was playing around with javascript objects to understand "this" and function context better. I stumbled across this problem. I get the error "obj2 is not defined" unless I run window.obj2() after assigning it, but I don't know why. Shouldn't it be enough to assign the function to window.obj2 without also executing it immediately afterwards? I know that you're not supposed to pollute the window object, this is just a test. Thanks!

window.obj2 = function(){
    console.log('obj2 in window.object',this);
}

window.obj2(); // problem when this line is commented out

(function () {

    var parent = {
        obj : function(){
            //console.log(this);
            obj2();
            this.obj2();
            window.obj2();
        },
        obj2 :function(){
            console.log('obj2 in parent',this);
        }
    }

    parent.obj();

}());

EXPLANATION

OP asks why does he have to execute the function after defining it in order for it to become defined later in the code... See what happens when you comment out the problem line.

15
  • Hello, the thing is, that i get an error message, unless I run window.obj2() globally. I don't understand why. Commented Feb 1, 2014 at 4:28
  • 2
    This code works fine: jsbin.com/ekUVIQE/1/edit The only problem would be if you tried to call obj2 before creating it, since function expressions don't get hoisted to the top of the scope like function declarations do. Commented Feb 1, 2014 at 4:28
  • +1 Seems like window methods get defined at the end of a script because if you run that code as two chunks, it works fine. Commented Feb 1, 2014 at 4:30
  • works perfectly fine..and you dont need to explicitly say window.obj2 = function(){.even when you declare it as function obj2 () {} it gets declared on window object Commented Feb 1, 2014 at 4:32
  • 1
    Where exactly are you getting the error? Commented Feb 1, 2014 at 4:32

2 Answers 2

5

Solution to the mystery:

You forgot a semicolon:

window.obj2 = function(){
    console.log('obj2 in window.object',this);
}; // <--

Without it, the code will be interpreted as

// I'm naming the functions to refer to them later
window.obj2 = function a(){
   ...
}(function b() { ... }());

I.e. the parenthesis around b are interpreted as call operation of a (just like you did with b itself: (function b() {...}()).

The engine first executes b in order to pass the return value as argument to a, and only after that the return value is assigned to window.obj2.

So, at the moment b is called, window.obj2 does indeed not exist yet.


So, the reason why adding window.obj2() makes it work is not because you are accessing window.obj2, but because it makes the code un-ambigious. The following parenthesis cannot be interpreted as call operation anymore. You could use any statement there, e.g.

window.obj2 = function(){
    console.log('obj2 in window.object',this);
}

"foo";

(function () {
    obj2();
}());
Sign up to request clarification or add additional context in comments.

4 Comments

Wow! Never would have guessed it was the semicolon! Thanks.
oh, of course! How many code reviews have I performed and still didn't see that?!! :-)
@user1870482: Yeah, this happens actually more often than you think ;) But still, it always takes ages to find that issue.
@ScottSauyet: Just what I thought! :D
-1

If you defined function window.obj2 inside the anonymous function which does call itself then it works fine, have a look code.

<script>
//window.obj2(); // problem

(function (window) {
    window.obj2 = function(){
        console.log('obj2 in window.object',this);
    }

    var parent = {
        obj : function(){
            //console.log(this);
            obj2();
            this.obj2();
            window.obj2();
        },
        obj2 :function(){
            console.log('obj2 in parent',this);
        }
    }

    parent.obj();

}(window));

</script>
<body>

</body>

4 Comments

yeah, but he was asking for why need to invoke window.obj2() after just defined it.
Probably because you didn't explain what the problem with the OP's code was.
@Felix Kling Is that reason enough for downvoting?
It can be. It depends on the question. Also people can downvote for whatever reason they want to.

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.