Scope of var and variables

余生长醉 提交于 2020-01-24 06:16:52

问题


If I have a function like

<cfscript>
function say(what) {
  var a = what;
  variables.b = what;
  return what;
}
</cfscript>

I thought the scope of a was variables, but dumping variables returns just b. What is the scope of a?


回答1:


Declaring a variable using the var keyword puts it into the local scope, not the variables scope.




回答2:


This really is a comment, but it is way too long. Consider the following code

<cfscript>
function doMath() {
   var a = 1;
   local.b = 2;
   return a + local.b;
   }
</cfscript>

At first glance on might think that var and local. have the same scope. After all they both exist only within the function. When then function is done, both variables cease to exist. End of story? Maybe not.

In ColdFusion, we have both implied scopes and implicit scopes.

url.a
form.a
cookie.a
session.a
application.a
local.a
arguments.a
myQuery.a

Are all different. If I have all of the above as valid variables and I say <cfoutput>#a#</cfoutput> which a do I get? ColdFusion goes through its list of implied scopes until it hit one that matches. And that is the one that gets displayed. So back to the question.

So when I am inside of a function, if I use var I am saying to ColdFusion, look through all the implied scopes until you find one that matches. If I use local.a, I am saying look in exactly one place and use that.

Benefits

I know exactly what variable I am picking up. If you are writing code that needs to be as fast as possible you won't use implicit scopes. If you are writing code that is the most readable, you won't use implicit scopes.

So no. var is not the same as local.




回答3:


Understanding scoping can help you avoid some issues that can be extremely difficult to track down. For all intents an purposes, var a puts a into the local scope, and it can be referenced as a local variable. And if declared afterwards, it will overwrite any a variable already in the local scope.

https://trycf.com/gist/faf04daa53194a5fad2e69e164518299/acf2016?theme=monokai

<cfscript>
function say() {
    local.a = "local" ; 
    var b   = "var" ;

    lv = local.b ; // We didn't explicitly assign b to Local scope. 

    try {
        v = variables ; // Let's dump the variables scope. 
    } catch (any e) {
        v = "Error: " & e.message ;
    }

    variables.nh = "Now here." ; // Explicitly populate variables scope.

    var c = "var c" ; // We have a variables scope, what happens to var?

    try {
        v2 = variables ; // Let's dump the variables scope. 
    } catch (any e) {
        v2 = "Error: " & e.message ;
    }

    var d = "var" ;
    local.d = "local" ;

    local.e = "local" ;
    var e = "var" ;

    return {
        a  : a ,       // Local.
        b  : b ,       // Var.
        d  : d ,       // Which one?
        e  : e ,       // Which one?
        el : local.e , // Which one?? 
        l  : lv ,      // Ref b in local scope.
        l2 : local ,   // Dump local scope.
        v  : v ,       // There doesn't seem to be a variables scope yet.
        v2 : v2        // Defined a variable scope and now here.
    } ;
}

writeDump(say());
</cfscript>

We can see above that declaring var b puts b into the local scope, and that the variables scope doesn't exist until we declare something into it. We can reference local.b, but variables.b can't exist. After we explicitly created and populated variables scope with nh, we create a var c. This doesn't go into the variables scope either, but into the local scope.

When a variable is declared with the same name in either local or by var, the last one declared will overwrite the other one (see d,e and el). Watch out for this.

Also note that the empty arguments scope from the function is also in the local scope.

On that note, my last two observation of scope things to watch out for:

https://trycf.com/gist/65b73e7a57d0434049d0eb9c0d5f9687/acf11?theme=monokai

<cfscript>
function ks() {
    variables.jay   = "Snoogins." ; // variables scope leaks out of function.
    local.silentbob = "____" ;      // local scope stays inside function.
}

function sayArgs(arg) {
    local.arg = "local" ; // Order after agruments in CF10 but not 2016.

    ks() ; // Run ks() function to instantiate jay and silentbob.

    return {
        arg    : arg ,       // CF10 = arguments scope. CF11+ = local scope.
        args   : arguments ,
        local  : local ,     // No leakage from ks().
        vars   : variables   // Jay leaks from ks().
    } ;
}

writeDump(sayArgs("argue")) ;
</cfscript>

Two things I noted here:

First, there is a difference between the order of evaluation of arguments and local scopes in CF10 vs later CF versions. Current CF2016 (or 2011+) behavior is that local scope inside of a function will not overwrite the arguments scope, but it will be evaluated first. The opposite happens in CF10: arguments is evaluated first. Lucee and Railo behave like ACF2016.

The second note has to do with variable leakage as it applies to variables and local. local will only exist inside the function that it is declared in. variables is more global and can be reached outside of the function.

https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming-language/using-coldfusion-variables/about-scopes.html << For ACF2016. Displays evaluation order with local over arguments.

http://www.learncfinaweek.com/week1/Scopes/ << Lists the order that ACF10 evaluates in, but the order of arguments and local are switched in later versions.

https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html << This is the documentation for ACF9. It lists the same order as ACF2016, but is different in ACF10. I don't have a copy of CF9 to test against right now, so I don't know how CF9 and earlier handle the evaluations.




回答4:


Let's go line by line (see the comments):

<cfscript>
function say(what) {

    // using the "var" keyword define a variable named "a" in the "local" scope
    // the "local" scope is private to the current function context
    // give to "a" the value of the "what" argument
  var a = what;


    // explicitly define a variable "b" in the "variables" scope 
    // the "variables" scope is available anywhere in the current template context
    // give to "b" the value of the "what" argument
  variables.b = what;


    // return the value of "what" argument
  return what;
}
</cfscript>

var is a keyword
variables is a scope
local is a private scope (also a keyword)

The local scope can be populated either using var a = "foo" or explicitly using local.a = "foo".




回答5:


In the current example, var a is available only within the scope of the function.



来源:https://stackoverflow.com/questions/47112598/scope-of-var-and-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!