var和变量的范围

时间:2017-11-04 15:59:32

标签: scope coldfusion cfml

如果我有像

这样的功能
<cfscript>
function say(what) {
  var a = what;
  variables.b = what;
  return what;
}
</cfscript>

我认为a的范围是variables,但转储variables只返回b。什么是范围?

5 个答案:

答案 0 :(得分:4)

这确实是一个评论,但它太长了。请考虑以下代码

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

乍一看可能认为varlocal.具有相同的范围。毕竟它们都只存在于函数中。当函数完成时,两个变量都不复存在。故事结局?也许不是。

在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.

不同

答案 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 aa放入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>

Output 1

我们可以在上面看到声明var bb置于local范围内,并且variables范围在我们向其声明内容之前不存在。我们可以引用local.b,但variables.b不能存在。在我们使用variables明确创建并填充nh范围后,我们创建了一个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>

Output 2

我在这里注意到两件事:

首先,CF10与后来的CF版本中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&lt;&lt;对于ACF2016。显示local超过arguments的评估订单。

http://www.learncfinaweek.com/week1/Scopes/&lt;&lt;列出ACF10评估的顺序,但argumentslocal的顺序在更高版本中切换。

https://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html&lt;&lt;这是ACF9的文档。它列出了与ACF2016相同的订单,但在ACF10中有所不同。我现在没有CF9的副本进行测试,因此我不知道CF9及其早期如何处理评估。

答案 4 :(得分:0)

在当前示例中,var a仅在函数范围内可用。