1

Let's say I have some function on top of a script that, when given a hash mapping function name {string} to functions defined below it, so in code:

collect({"f1" : f1, "f2" : f2 })

The problem is if collect is at the top of the page, then f1, f2, .. will point to undefined since those functions have, yet to be defined. The easy solution is to put collect at the bottom of the page. But if I stubbornly need it to sit at the top, how do I delay execution of collect until all other functions are parsed?

Note, the rest of the functions are defined in form:

var name; 
name = function(){ .. }

Bonus question:

If I can define collect such that instead of passing in a has mapping name to function, I can just pass in a list of functions, or a list of strings, and achieve the same effect, it would be even better. So in code, something like

collect([f1,f2]) 
collect(["f1","f2"])

Update: I think I'm not being explicit about what I am asking. I am looking specifically to delay the execution of a function until the rest of the file is parsed. I am not looking to replicate this behavior via some other hack that changes the semantics of what I am trying to do.

xiaolingxiao
  • 4,340
  • 3
  • 27
  • 64
  • 3
    Why don't you define them explicitly? `function name() {}` – Niccolò Campolungo Sep 14 '13 at 20:28
  • Well if you want to be stubborn for no reason, then load the script as text instead of script, take it apart with regular expressions or something, and then first `eval` the second part and then the first – that stubborn/stupid enough for your taste? :-P – CBroe Sep 14 '13 at 20:29
  • I am not asking about callbacks, the other functions in the file are defined but not executed. They are just sitting there, so no way will they be calling this function on top. Unless you are suggesting I write a special function on the bottom of the page just so it can call `collect`, which isn't really a solution – xiaolingxiao Sep 14 '13 at 20:30
  • 1
    If you can explain why `collect` can't go at the bottom, maybe we can get a better idea of the question. – Kendall Frey Sep 14 '13 at 20:30
  • collect is an alias for `export`, which by convention should go on top of the file. So I am home-brewing a module system – xiaolingxiao Sep 14 '13 at 20:32
  • @LightStyle, no I don't want an entire file to go inside the immediately invoked function `(function( w ) { .. })( Window )`, and then inside `collect` – xiaolingxiao Sep 14 '13 at 20:34
  • @chibro2, I don't understand you answer. Can you please be more specific? What's wrong with defining the explicitly? – Niccolò Campolungo Sep 14 '13 at 20:35
  • do you mean like `export({ "hi" : function(){ console.log("hihi") })`. It's a matter of style, and at any rate I am really trying to see if it's possible to delay execution of a function, not like replicating the outcome in some other way. – xiaolingxiao Sep 14 '13 at 20:37
  • No, I'm saying that you should use function **declaration** instead of function expression. Anyway I understand that this is not going to answer your question; I guess there is no a true way of doing this without some "hacks" – Niccolò Campolungo Sep 14 '13 at 20:40
  • @Cbroe no we both know that's not helpful – xiaolingxiao Sep 14 '13 at 20:41
  • possible duplicate of [$(document).ready equivalent without jQuery](http://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery) – Barmar Sep 14 '13 at 20:49
  • @LightStyle oops sorry I didn't understand your original post, actually function declaration is acceptable solution, thanks :) – xiaolingxiao Sep 14 '13 at 20:51

2 Answers2

2

You could delay the execution of collect until after everything ran, e.g. using setTimeout:

function collect(o) { /.../ }

setTimeout(function() { collect({"f": f}); }, 0);

var f = function f() {}

The engine won't execute any event callbacks incl. timeout handlers until the current execution context is done (well, not exactly, see 7.3 Timers, in particular Steps 11. + 12.). Here is a fiddle with some artificial delay, demoing this stuff.

nmaier
  • 29,828
  • 5
  • 59
  • 75
0

I think it's time you learned about objects and prototypes. Create an object function Whatever(){} with prototype Whatever.prototype = { f1: ..., f2: ...} and make functions refer to other functions using this:

function Whatever() {};
Whatever.prototype = {
  f1: function() {
    // don't care that this function doesn't exist yet,
    // because what an object is built from this prototype,
    // ALL functions will exist at the same time. Handy.
    this.f2("this is a string");
  },
  f2: function(s) {
    console.log(s);
  }
}; 
var what = new Whatever();
what.f2("lol");
what.f1();
Mike 'Pomax' Kamermans
  • 40,046
  • 14
  • 84
  • 126
  • I do know how to implement prototype inheritance. This is not a question about how to replicate the desired order of function call via some other implementation, it's a question about to delay the execution of a function until the rest of the file is parsed – xiaolingxiao Sep 14 '13 at 20:36
  • no, it really is about replicating. What you want to do is not how to do what you want to achieve. Prototype inheritance is a matter of `Whatever.prototype = new ParentObject(); Whatever.prototype.constructor = Whatever`. – Mike 'Pomax' Kamermans Sep 15 '13 at 00:13
  • I think my question is misunderstood. I am explicitly asking about order of function execution. The function 'collect' is completely orthogonal to all functions below, they do not share state or operate on the same data, thus do not form a cohesive object in any way. what's happening here is I'm asking how to make bacon that's crispy on the outside but chewy on the inside, and many people here is saying no no, we solved this problem already with the over easy, you need to use eggs. – xiaolingxiao Sep 15 '13 at 10:13
  • your simile doesn't hold up. you're asking how to cook bacon that's crispy on the outside but chewy on the inside at 200F in the oven (you already decided on the approach), and we're telling you not to use an oven at 200F but use a good skillet instead. Based on your updated question, your question is a non issue: put your call at the end of the file, done. It'll execute last, everything else is already declared. If that doesn't work, you're still not properly explaining what you need. I recommend a jsfiddle example with "I expected X, but it's doing Y. How do I X?" – Mike 'Pomax' Kamermans Sep 15 '13 at 17:38
  • Like it says in the question, I need to function to sit at the top of the page – xiaolingxiao Sep 15 '13 at 18:12
  • but you don't in the slightest explain why it has to be at the top. As a JavaScript programmer, I'm going to tell you to just move the function. You control the code, exercise that control. If you can't tell us why that function has to be up top, because at this point it seems like you're trying to write based on programming paradigms that do not apply to JavaScript programming. – Mike 'Pomax' Kamermans Sep 15 '13 at 18:26