6

I'm studying object literals and self-executing functions in Javascript. Looking through some YUI code I came across some methods of an object literal that execute themselves. My question is why the following code does not alert 'Ohai Mark!';

var bar = {
    alert: function () {
        window.alert('Ohai Mark!');
    },
    init: (function () {
        bar.alert();
    }())
};

2 Answers 2

9

To explain in detail:

> var bar = {

In javascript, declarations are processed first so bar exists as a variable before execution begins.

>     alert: function () {
>         window.alert('Ohai Mark!');
>     },
>     init: (function () {
>         bar.alert();
>     }())

bar will be assigned a value after the expression on the right hand side is evaluated. During that evaluation, bar has whatever value it had when the statement (the entire line) was reached. It is currently undefined, and so it does not have an alert property yet.

> };
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, thank you. So I suppose a better way to do it would be to eliminate the self-invoking method and just have the line bar.init() after the assignment? How would you go about doing this? I saw another question that suggested doing something like var bar = (function () { function alert() { alert('hi'); } return {alert: alert}}()) then simply calling alert like so bar.alert(). Do you think that is a better way?
Zach, that's an excellent way to properly scope your functions. This way, every function can be scoped in the 'bar' namespace, and this further allows you to have private / public functions. Go for it!
3

When executing the code, "bar" is defined but not yet assigned the resultant JSON object at the point which the init() method is defined (and about to assigned to the bar object) [EDITED]. As init's function-scope is properly defined, I would declare the function there, like so:

var bar = {
  init: (function () {
      var alert = function () {
        window.alert('Ohai Mark!');
      };

      alert(); //this will execute the code above
  }())
};

See Javascript Garden#namespaces and scopes. [EDIT] You might think this akin to:

(function() {
  var c = c + 1;
})();

8 Comments

+1 , but more correctly, bar is defined before any code is run, but the object with property alert has not yet been assigned at the point that the function is called.
Wow, excellent catch and you made that way harder to explain. Further feedback would be truly appreciated (see edit)
I would explain it as bar has not been assigned a value until after the RHS expression (not "JSON object") has been evaluated, so calling bar.alert() during evaluation of the expression (i.e. before it exists) results in an error.
The referenced article has a large number of errors, it should not be offered to anyone inexperienced with javascript or ECMAScript.
And here I've been assuming Javascript Garden had it all right. Do you have something to reference faults / inaccuracies of JSG?
|

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.