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>

乍一看可能会认为varlocal.有相同的作用域。毕竟它们都只存在于函数中。当 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,我的意思是只在一个地方查找并使用它。

好处

我确切地知道我在选择什么变量。如果您正在编写需要尽可能快的代码,则不会使用隐式范围。如果您正在编写可读性最高的代码,则不会使用隐式作用域。

所以没有。 varlocal.

不同

在当前示例中,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 aa 放入 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 bb 放入 local 范围,并且 variables 范围不存在,直到我们声明一些东西到它.我们可以引用 local.b,但 variables.b 不能存在。在我们使用 nh 显式创建并填充 variables 范围后,我们创建了一个 var c。这也不进入 variables 范围,而是进入 local 范围。

当在 localvar 中声明同名变量时,最后声明的变量将覆盖另一个(参见 deel)。 注意这一点。

另请注意,函数中的空 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 与更高版本的 argumentslocal 作用域的求值顺序有所不同。当前的 CF2016(或 2011+)行为是函数内部的 local 作用域不会覆盖 arguments 作用域,但会首先对其求值。相反的情况发生在 CF10 中:首先计算 arguments。 Lucee 和 Railo 表现得像 ACF2016。

第二个音符与变量泄漏有关,因为它适用于 variableslocallocal 将仅存在于声明它的函数内部。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 计算的顺序,但是 argumentslocal 的顺序在以后的版本中被调换了。

https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html << 这是 ACF9 的文档。它列出的顺序与 ACF2016 相同,但在 ACF10 中有所不同。我现在没有要测试的 CF9 副本,所以我不知道 CF9 和更早版本如何处理评估。