如果我有像
这样的功能<cfscript>
function say(what) {
var a = what;
variables.b = what;
return what;
}
</cfscript>
我认为a的范围是variables
,但转储variables
只返回b
。什么是范围?
答案 0 :(得分:4)
这确实是一个评论,但它太长了。请考虑以下代码
<cfscript>
function doMath() {
var a = 1;
local.b = 2;
return a + local.b;
}
</cfscript>
乍一看可能认为var
和local.
具有相同的范围。毕竟它们都只存在于函数中。当函数完成时,两个变量都不复存在。故事结局?也许不是。
在ColdFusion中,我们有隐含的范围和隐式范围。
url.a
form.a
cookie.a
session.a
application.a
local.a
arguments.a
myQuery.a
都不同。如果我将上述所有内容都作为有效变量,我说<cfoutput>#a#</cfoutput>
我得到a
? ColdFusion会查看隐含范围的列表,直到找到匹配的范围。这就是显示的那个。回到这个问题。
所以当我在函数内部时,如果我使用var
我对ColdFusion说,请查看所有隐含的范围,直到找到匹配的范围。如果我使用local.a
,我说要查看一个地方并使用它。
<强>优势强>
我确切地知道我正在接受什么变量。如果您编写的代码需要尽可能快,那么您将不会使用隐式作用域。如果您编写的代码最具可读性,则不会使用隐式作用域。
所以没有。 var
与local.
答案 1 :(得分:2)
让我们一行一行(见评论):
<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
是关键字
variables
是范围
local
是私有范围(也是关键字)
可以使用local
或明确使用var a = "foo"
填充local.a = "foo"
范围。
答案 2 :(得分:2)
使用var
关键字声明变量会将其放入local
范围,而不是variables
范围。
答案 3 :(得分:2)
了解范围可以帮助您避免一些极难以追踪的问题。对于所有意图,var a
将a
放入local
范围,并且可以将其引用为local
变量。如果之后声明,它将覆盖a
范围内已有的local
变量。
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>
我们可以在上面看到声明var b
将b
置于local
范围内,并且variables
范围在我们向其声明内容之前不存在。我们可以引用local.b
,但variables.b
不能存在。在我们使用variables
明确创建并填充nh
范围后,我们创建了一个var c
。这不会进入variables
范围,而是进入local
范围。
如果在local
或var
中使用相同的名称声明变量,则声明的最后一个变量将覆盖另一个变量(请参阅d
,e
和el
)。 注意这一点。
另请注意,该函数中的空arguments
范围也位于local
范围内。
就此而言,我最后两次观察范围事项需要注意:
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>
我在这里注意到两件事:
首先,CF10与后来的CF版本中arguments
和local
范围的评估顺序存在差异。当前的CF2016(或2011+)行为是函数内的local
范围不会覆盖arguments
范围,但会首先评估它。相反的情况发生在CF10中:首先评估arguments
。 Lucee和Railo表现得像ACF2016。
第二个注释与变量泄漏有关,因为它适用于variables
和local
。 local
只存在于声明它的函数内。variables
更全局,可以在函数外部到达。
https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming-language/using-coldfusion-variables/about-scopes.html&lt;&lt;对于ACF2016。显示local
超过arguments
的评估订单。
http://www.learncfinaweek.com/week1/Scopes/&lt;&lt;列出ACF10评估的顺序,但arguments
和local
的顺序在更高版本中切换。
https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html&lt;&lt;这是ACF9的文档。它列出了与ACF2016相同的订单,但在ACF10中有所不同。我现在没有CF9的副本进行测试,因此我不知道CF9及其早期如何处理评估。
答案 4 :(得分:0)
在当前示例中,var a
仅在函数范围内可用。