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?

Chris Middleton
  • 5,654
  • 5
  • 31
  • 68
  • 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. – Loenix Sep 18 '14 at 15:55

2 Answers2

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!

Chris Middleton
  • 5,654
  • 5
  • 31
  • 68
Nicolas Albert
  • 2,586
  • 1
  • 16
  • 16
  • This makes sense. I can't find it explicitly written anywhere though. I did find [this other SO answer](http://stackoverflow.com/a/3887590/2407870) which talks about it. – Chris Middleton Sep 18 '14 at 16:15
  • 1
    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. – slebetman Sep 18 '14 at 16:23
  • 1
    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) – slebetman Sep 18 '14 at 16:26
  • 1
    If all the above sounds a bit scary (writing code in a language you cannot really completely know), it was. Very, very scary. – slebetman Sep 18 '14 at 16:27
  • 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! – Chris Middleton Sep 18 '14 at 16:30
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.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 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); };` – Chris Middleton Sep 18 '14 at 16:12
  • 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. – Aaron Digulla Sep 19 '14 at 08:48