var 和变量的范围
Scope of var and variables
如果我有这样的函数
<cfscript>
function say(what) {
var a = what;
variables.b = what;
return what;
}
</cfscript>
我认为 a 的范围是 variables
,但转储 variables
returns 只是 b
。 a的范围是什么?
这确实是一条评论,但是太长了。考虑以下代码
<cfscript>
function doMath() {
var a = 1;
local.b = 2;
return a + local.b;
}
</cfscript>
乍一看可能会认为var
和local.
有相同的作用域。毕竟它们都只存在于函数中。当 then 函数完成时,两个变量都不复存在。故事结局?也许不是。
在 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.
不同
在当前示例中,var a
仅在函数范围内可用。
让我们逐行分析(查看评论):
<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
是一个 scope
local
是一个 私有范围 (也是关键字)
可以使用 var a = "foo"
或显式使用 local.a = "foo"
填充 local
范围。
使用 var
关键字声明变量会将其放入 local
范围,而不是 variables
范围。
了解范围界定可以帮助您避免一些极其难以追踪的问题。出于所有目的,var a
将 a
放入 local
范围,它可以作为 local
变量引用。如果之后声明,它将覆盖任何已经在 local
范围内的 a
变量。
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
不能存在。在我们使用 nh
显式创建并填充 variables
范围后,我们创建了一个 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 与更高版本的 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 << 对于 ACF2016。显示 local
高于 arguments
的评估顺序。
http://www.learncfinaweek.com/week1/Scopes/ << 列出了 ACF10 计算的顺序,但是 arguments
和 local
的顺序在以后的版本中被调换了。
https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html << 这是 ACF9 的文档。它列出的顺序与 ACF2016 相同,但在 ACF10 中有所不同。我现在没有要测试的 CF9 副本,所以我不知道 CF9 和更早版本如何处理评估。
如果我有这样的函数
<cfscript>
function say(what) {
var a = what;
variables.b = what;
return what;
}
</cfscript>
我认为 a 的范围是 variables
,但转储 variables
returns 只是 b
。 a的范围是什么?
这确实是一条评论,但是太长了。考虑以下代码
<cfscript>
function doMath() {
var a = 1;
local.b = 2;
return a + local.b;
}
</cfscript>
乍一看可能会认为var
和local.
有相同的作用域。毕竟它们都只存在于函数中。当 then 函数完成时,两个变量都不复存在。故事结局?也许不是。
在 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.
在当前示例中,var a
仅在函数范围内可用。
让我们逐行分析(查看评论):
<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
是一个 scope
local
是一个 私有范围 (也是关键字)
可以使用 var a = "foo"
或显式使用 local.a = "foo"
填充 local
范围。
使用 var
关键字声明变量会将其放入 local
范围,而不是 variables
范围。
了解范围界定可以帮助您避免一些极其难以追踪的问题。出于所有目的,var a
将 a
放入 local
范围,它可以作为 local
变量引用。如果之后声明,它将覆盖任何已经在 local
范围内的 a
变量。
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
不能存在。在我们使用 nh
显式创建并填充 variables
范围后,我们创建了一个 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 与更高版本的 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 << 对于 ACF2016。显示 local
高于 arguments
的评估顺序。
http://www.learncfinaweek.com/week1/Scopes/ << 列出了 ACF10 计算的顺序,但是 arguments
和 local
的顺序在以后的版本中被调换了。
https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html << 这是 ACF9 的文档。它列出的顺序与 ACF2016 相同,但在 ACF10 中有所不同。我现在没有要测试的 CF9 副本,所以我不知道 CF9 和更早版本如何处理评估。