5

我已经为 ColdFusion 编程超过 15 年,但从未遇到过这种情况。这是复制行为的代码:

<cfset _run()>
<cffunction name="_run">
  <cfset variables.dataArray=ArrayNew(1)>
  <cfset local.data={
    area="profile"
  }>
  <cfset _append(data=local.data,field="name")>
  <cfset _append(data=local.data,field="phone")>
  <cfdump var="#variables.dataArray#" label="dataArray">
</cffunction>
<cffunction name="_append">
  <cfargument name="data" type="struct" required="yes">
  <cfargument name="field" type="string" required="yes">
  <cfdump var="#arguments#" label="arguments">
  <cfset arguments.data.field=arguments.field>
  <cfset ArrayAppend(variables.dataArray,arguments.data)>
</cffunction>

如您所见,这就是我所做的:

  1. 在变量范围内初始化一个数组以使其全局可访问
  2. 在本地范围内初始化结构(local.data)
  3. 通过将数据调用到 _append 函数来附加第一个字段项(名称)
  4. 以相同的方式附加第二个字段项(电话)

此代码将产生以下输出:

输出转储

如您所见,当您可能期望第一个索引应该具有 field="name" 时,代码会生成一个包含重复条目的数组。如您所见,第二次调用 _append 的数据值包含属性“字段”,其值为“名称”。从我们第一次调用函数开始,它似乎就一直停留在参数范围内?这怎么可能。我认为参数范围被隔离在 cffunction 标记内?

但是如果我用这个替换 _append 函数:

<cffunction name="_append">
  <cfargument name="data" type="struct" required="yes">
  <cfargument name="field" type="string" required="yes">
  <cfdump var="#arguments#" label="arguments">
  <cfset local.data=Duplicate(arguments.data)>
  <cfset local.data.field=arguments.field>
  <cfset ArrayAppend(variables.dataArray,local.data)>
</cffunction>

它将给出以下输出:

输出 2 的转储

如您所见,在将“字段”附加到它之前复制 arguments.data 可以解决问题。请注意,只是这样做:

<cfset local.data=arguments.data>

还不够。

有人可以解释参数范围的这种行为吗?

4

1 回答 1

4

因此,经过一番研究,我在 Adob​​e Coldfusion 文档页面上发现了这一点(由我完成的文本加粗):

关于参数范围

所有函数参数都存在于它们自己的范围内,即 Arguments 范围内。Arguments 范围在函数调用的整个生命周期中都存在。当函数返回时,作用域及其变量被销毁。但是,破坏 Argument 范围不会破坏ColdFusion 通过引用传递给函数的变量,例如结构或查询对象。您用作函数参数的调用页面上的变量继续存在;如果函数更改了参数值,调用页面中的变量会反映更改后的值

这让我大开眼界,它会让我在未来远离麻烦:)

于 2017-12-15T11:43:04.567 回答