问题
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 keywordvariables
is a scopelocal
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