I always use global variables when running doScripts(). I've always found it simpler than getting arguments just right...

Just make a single global object or function to store your globals and don't worry about theory. It's perfectly readable and maintainable. With InDesign scripting globals are pretty much a necessity of life. In fact, global functions can really improve performance in certain cases.

Just make sure to always use kConstant for global contants and gVariable for global variables, and there's not much room for confusion...

One example: I always define
kAppVersion = parseFloat(app.version);
I then use that global varaible probably dozens of times.
Is that bad? I don't think so. If you can avoid hitting the InDesign DOM, it's a good thing. Hitting the InDesign DOM is a whole lot worse than an idealogical aversion to global variables...

Marc Autret:

app.doScript supports inline scripts as 1st argument and then is similar to eval(). Anyway, this does not solve the technical problem of passing full object structures to another script—I mean, another script file.

1) Apparently the 3rd arg to app.doScript only supports an array of scalars (Number, Boolean, String), although you can also include Arrays, provided that each element is itself a scalar or an array of scalar (recursively). E.g.:

app.doScript( myScript, undefined, [ true, "hello", [1,2,["aaa","bbb"]], 18 ] );

But simple key-value pair objects won't pass through! More precisely, they are recovered as empty objects: ({})

2) Contrary to what I thought the doScript's array of arguments doesn't seem connected to app.scriptArgs—which IMHO is as stupid as confusing! However the ScriptArg approach is not much more promising, as the ScriptArg's getters/setters only undertand strings as ultimate values—according to the doc.

3) Finally, if one needs to pass a (simple) object to myScript, maybe the only way is to uneval the structure—or .toSource()—in order to pass a string and to recover the whole thing via eval() or a dedicated Function. Here is a proof of concept:

function myScript(args)  
    // Extract the passed object  
    var o = (Function('return '+args[0]))();  
    alert( ); // => 1  
    alert( ); // => "Bar"  
    o.doSth();        // -> alert a "hello" msg  
var myObj = {  
    foo: 1,  
    bar: "Bar",  
    doSth: function(){alert("hello!");}  
app.doScript(myScript, ScriptLanguage.JAVASCRIPT, [myObj.toSource()]); 

Example of sending arguments in array:

var argsArray = [42, 1701];  
app.doScript(runFoo, ScriptLanguage.JAVASCRIPT, argsArray, UndoModes.FAST_ENTIRE_SCRIPT, "Test");  
function runFoo(aFooArray) {  
     for (var i = 0; i < aFooArray.length; i++) {