skip to Main Content

This is a simple script that’ll log the content of text from a Photoshop file.

var numOfLayers = app.activeDocument.layers.length;
var resultStr = "";

doAllLayers();
alert(resultStr);

function addToString(alayer)
{
  if (alayer.kind == "LayerKind.TEXT")
  {
    var c = alayer.textItem.contents;
    resultStr += c;
  }
}

// main loop
function doAllLayers()
{
  for (var i = numOfLayers -1; i >= 0; i--)
  {
      var thisLayer = app.activeDocument.layers[i];
      addToString(thisLayer);
  }
}

It works fine but I really should be passing a string into the function to add to itself, however it works.
How does the scope of JavaScript allow this to happen? Are declared local variables still accessed by functions or is it another trick I’m missing?

2

Answers


  1. Here are some basic rules to variable scoping in JavaScript:

    • If defined with the var keyword, the variable is function-scoped. That is, the variable will be scoped to either the closest containing function, or to the global context if there is no containing function.
      Example:
       
    // globally-scoped variable (no containing function)
    var foo = 'bar';
    
    function test() {
        // function-scoped variable
        var foo2 = 'bar2';
    
        if (true) {
            // still function-scoped variable, regardless of the if-block
            var foo3 = 'bar3';
        }
    
        // see?
        console.log(foo3); // --> 'bar3'
    }
    
    • If defined with the let keyword (ES6+), then the variable is block-scoped (this behavior more closely resembles most other C-family syntax languages). Example:
       
    // error: top level "let" declarations aren't allowed
    let foo = 'bar';
    
    function test() {
        // block-scoped variable (function are blocks, too)
        let foo2 = 'bar2';
    
        if (true) {
            // block-scoped variable (notice the difference
            // from the previous example?)
            let foo3 = 'bar3';
        }
    
        // uh oh?
        console.log(foo3); // --> ReferenceError: foo3 is not defined
    }
    
    • If defined with neither the var or let keywords (e.g., foo = bar), then the variable is scoped to the global context. Example:
       
    // globally-scoped variable
    foo = 'bar';
    
    function test() {
        // also globally-scoped variable (no var or let declaration)
        foo2 = 'bar2';
    
        if (true) {
            // still a globally-scoped variable
            foo3 = 'bar3';
        }
    }
    
    test();
    console.log(foo, foo2, foo3); // 'bar', 'bar2', 'bar3'
    

    In all of these cases, functions defined within scope of a variable still have access to the variable itself (technically you’re creating a closure, as the numOfLayers and resultStr variables are lexically in scope of your addToString and doAllLayers functions).

    Please note that the scoping rules are technically a little more nuanced than this, but you’re better off reading a more in-depth article at that point.

    Login or Signup to reply.
  2. You have defined var resultStr = ""; outside function which is a global variable. you can access this global variable inside addToString() and start concatenating to it. Note that inside the method you have not declared var resultStr = ""; else it would have been a different variable local to that method.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search