0

I'm doing some coding on a program called illustrator which allows you to use JavaScript. This is driving me crazy and I think it's related to closures but I'm not sure if it is or I'm just missing something.

I have the following code:

function runSomeStuff() {
  // some stuff gets done here unrelated variables set
  // after I have the following for loop which opens the document

  for (var currentTemplate = 1; currentTemplate <= 3; currentTemplate++){

    // opens file and does a few if statements... works fine.
    // here I have another for loop where the problem comes up
    for (var i = 1; i <= 18; i++) {
      // run some code here
    }
  }

}

The way it should work is that it should loop 3 times over the first for function which contains the other for function. So it should work like this.

First for function runs

Second for inside of the first runs 17 times then exits, does what it needs to then begins to run again.

The problem is after the first for function runs once, when it loops back again it won't run. The second for function doesn't run again. I added an alert for var i and it gave me 19 when it was trying to run the second time. I would expect var i to be 1 again since it's being re called on the second run. It appears even after it exists it i retains it's value when it was in the for loop so that it's false since i would be greater than 18.

EDIT: Because of the program it's being used in I can't use let or const.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
FabricioG
  • 2,204
  • 1
  • 21
  • 44
  • 1
    Can you show your actual code, please? Does opening the document or file involve anything asynchronous? – Bergi Mar 12 '19 at 22:50
  • 1
    Loops are statements, their bodies are blocks. No functions involved. Does your actual code have functions in there? – Bergi Mar 12 '19 at 22:50
  • Sounds like the `var i = 1` isn't interpreted or not actually in the right place. The part of the code you've shown should work. – Bergi Mar 12 '19 at 22:51
  • Can you tell use more about that "*program called illustrator*"? What engine does it use? Is there any documentation available? – Bergi Mar 12 '19 at 22:52
  • Yes it uses jsx to communicate with it's engine. Adobe illustrator jsx @Bergi scripting.https://www.adobe.com/content/dam/acom/en/devnet/illustrator/pdf/Illustrator_JavaScript_Scripting_Reference_2017.pdf – FabricioG Mar 12 '19 at 22:53

2 Answers2

0

The reason this might happen is due to variable hoisting. I'd recommend checking out if anything changes if you declare your variables at the first line of the function:

function runSomeStuff() {
  var currentTemplate, i;

  // some stuff gets done here unrelated variables set
  // after I have the following for loop which opens the document

  for (currentTemplate = 1; currentTemplate <= 3; currentTemplate++){

    // opens file and does a few if statements... works fine.
    // here I have another for loop where the problem comes up
    for (i = 1; i <= 18; i++) {
      // run some code here
    }
  }
}

If the above doesn't work you might want to try managing your own scopes, by moving the for loops into IIFEs:

function runSomeStuff() {
  // some stuff gets done here unrelated variables set
  // after I have the following for loop which opens the document

  (function () {
    for (var currentTemplate = 1; currentTemplate <= 3; currentTemplate++){

      // opens file and does a few if statements... works fine.
      // here I have another for loop where the problem comes up
      (function () {
        for (var i = 1; i <= 18; i++) {
          // run some code here
        }
      })();
    }
  })();
}

This clutters things up quite a bit, but your loops will have their own scope without the use of the let keyword.

3limin4t0r
  • 13,832
  • 1
  • 17
  • 33
0

The reason this is happening is most likely do to variable scoping. This means your variables are being moved to the top of the function when declared. To avoid this, you can declare your variables in this manner:

let i = 0;
let str = "Hello";
let arr = [1, 2, 3];

let allows your variables to be declared when first mentioned, and should clear up the problem. I use let all the time, and my scoping issues are gone.

N8Javascript
  • 107
  • 9
  • > EDIT: Because of the program it's being used in I can't use let or const. – Isaac Mar 13 '19 at 01:18
  • Not sure what it means but I think OP don't accept answer with `let`/`const` – Isaac Mar 13 '19 at 01:19
  • Oh, okay. The good news is, you can get let by entering your code in the BABEL repl (https://babeljs.io/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=MYGwhgzhAEBiD28DeAoa0DEAjMAnA3GtAOYCmALtALYCeOuAFAJSrrq4UCuuAdtOQAsAlhAB02PEQC-KGUA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=es2015%2Creact%2Cstage-2&prettier=true&targets=&version=7.3.3), and then taking the result and copying and pasting it into your code. – N8Javascript Mar 13 '19 at 01:41
  • Does Babel know about extendscript? Extendscript is Adobe's own subset of JS, particularly for running inside CC apps like Illustrator, Photoshop and After Effects. – stib Mar 14 '19 at 02:52
  • I was thinking that regardless of the code, babel could still transpile let. – N8Javascript Mar 14 '19 at 11:07