在CFScript中,循环变量需要使用var关键字声明吗?

9

在使用CFML和CF9时,我通常会对循环变量进行var范围限定,例如在这种情况下是local.i

<cfloop list="#this.list#" index="local.i">
  <cfif Len(local.i) GT 10>
    // do something
  </cfif>
</cfloop>

最近我开始将一些东西转换为CFScript,但是(让我失望的是,在CFScript中没有办法循环列表),我想知道是否仍然需要在循环变量上使用var scope,并且如何使用:

for (i = 1; LTE ListLen(this.list); i = i + 1 ) {
  if (Len(ListGetAt(this.list, i) GT 10)) {
    // do something
  }
}

我应该使用local.i = 1local.i = local.i + 1代替我的示例代码吗?这是必要的吗? 编辑:我还应该问一下我的CFML循环的CFScript形式是否正确;我问这个问题是因为我刚刚注意到我的CFML循环使用逗号和空格作为delimiter参数,而在CFScript版本的循环中似乎不存在这种情况。

1
有一件事我想提醒一下——除非你的“做某事”可以改变列表的长度,否则我建议将其存储在一个变量中,并循环到该变量。据我理解,按照你目前的写法,listlen() 操作将在每次循环时都被调用。 - Ben Doom
2个回答

8

如果您不指定变量作用域,所有函数仍默认使用变量作用域。如果省略作用域,则不具备线程安全性。在以前应该使用 var 的地方,现在应该使用 local

至于逗号加空格分隔符,有两点需要注意:

  1. In case you aren't aware, the delimiters argument of list function is not for multi-character delimiters, it is for multiple delimiters; so your list will be split for each occurrence of a comma, as well as each occurrence of a space.

  2. You use the same argument as part of your listLen and listGetAt methods, like so:

    for (i = 1; LTE ListLen(this.list, ', '); i = i + 1 ) {
      if (Len(ListGetAt(this.list, i, ', ') GT 10)) {
        // do something
      }
    }
    

请确认一下,当您说“UDFs仍然使用变量作用域”时,该定义是否包括我在CFC组件中声明的任何函数? - Mohamad
1
不,CFC 中的任何方法都将默认为本地作用域。我所指的 UDF 可以出现在任何其他地方(例如自定义标签、cfm 模板等)。 - Adam Tuttle
2
未经作用域限定的变量将默认为该变量的作用域,因此您需要确保使用新的“local”作用域或使用“var”关键字对所有本地变量进行作用域限定。 - Tony Nelson
实际上,Tony,你是完全正确的。我对于没有指定范围的默认值感到困惑。我会相应地更新我的答案。谢谢! - Adam Tuttle
在CF9及以上版本中,您可以使用<=代替LTE,>代替GT,以及i++代替i = i+1。 - RHPT

6

正如Adam所说,你肯定需要使用本地范围(local scope),但在循环的情况下,为了可读性,我认为使用“var”关键字而不是“local”前缀是有充分理由的。使用CF9,你不再被强制将变量声明放在函数顶部,因此你只需要在所有索引“i”变量的“for”条件语句中添加“var”,就可以使所有变量线程安全。

结合Ben提出的节省循环前列表长度的好方法,并使用更简洁的i++递增样式,你的代码应该是这样的:

var listLength  =   ListLen( this.list );
for (var i = 1; LTE listLength; i++ ) {
    if (Len(ListGetAt(this.list, i) GT 10)) {
    // do something
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接