1

When writing an API, I tend to like putting the functions in a top-down order, with the most exposed functions at the top, and the helper functions at the bottom. However, when defining functions with var rather than the magic function delcaration, a function cannot be used before it's defined. So what about if we have an object called $company and we're defining its methods. Can I safely order my JS in this fashion?

var $company = {};

$company.foo = function(x) {
    $company.bar(x*x); // used in definition, but not called directly - ok?
};

// $company.bar(6) // this would produce an error

$company.bar = function(x) {
    alert(x);
};

It seems to work in my current version of Firefox, but I'd like to know if it's defined behavior. Are there any versions of IE where this breaks?

1
  • 1
    JS will use your function when you call it, so when you are declaring foo, bar may not exist, but it should exist when foo is called. Commented Sep 18, 2014 at 15:55

2 Answers 2

1

Yes you can.

Functions are only defined, not executed.

The JS engine executes each line of your file :

var $company = {};
$company.foo = ...;
$company.bar = ...;

And later, at $company.foo execution, $company.bar is defined!

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

5 Comments

This makes sense. I can't find it explicitly written anywhere though. I did find this other SO answer which talks about it.
As the author of the referenced answer and a long time javascript hacker I can tell you a bit about how javascript/ECMAscript spec is written. First there was Netscape's implementation (only code, no spec) then Microsoft copied it as closely as possible (including bugs) then people decided that there ought to be a standard (mainly due to fears that Microsoft will evolve their js engine to be 100% incompatible with everyone else). This process goes on to this day with features Apple invented becoming a "standard" called HTML5, syntax Microsoft invented becoming part of SVG etc.
Perhaps due to this, the javascript spec is actually an attempt at documenting, as closely as possible, current implementations of javascript (except the parts the standards committee cannot agree on). Therefore, a lot of the parts that browsers just happen to have exactly compatible behaviors are overlooked as obvious and remains undocumented. In the old days we had to write test scripts to figure out how js worked (especially with IE since we don't have access to the source code)
If all the above sounds a bit scary (writing code in a language you cannot really completely know), it was. Very, very scary.
Hah, I was just reading some of your other answers. :P The answer of yours I linked was really well written and I think I get it now. Thanks for the comments!
0

Yes, this works since no browser (or no JavaScript engine) makes assumptions about what is to the right of a . until it has to evaluate the expression to the left.

But many people don't like this kind of "look ahead" and use callback functions instead:

 $company.foo = function(x, callback) {
      callback(x*x);
 }

This code is more obvious, more flexible since it can call almost anything, you can curry it, etc.

2 Comments

Thanks. I'm not sure it depends on the . explicitly though, since the following also produces no error: var a = function() { b(); }; var b = function() { alert(1); };
Well, there are two effects here: JavaScript will parse the function body (to check for syntax errors) but it won't make many assumptions about what the individual bits mean. So in a sense, you have the same situation with function bodies and .: As long as the syntax is OK, JavaScript doesn't care (yet) if the body/right hand side makes sense.

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.