5

私は 15 年以上 ColdFusion をプログラミングしてきましたが、これに遭遇したことはありません。動作を再現するコードは次のとおりです。

<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. 同じ方法で 2 番目のフィールド項目 (phone) を追加します

このコードは、次の出力になります。

出力のダンプ

ご覧のとおり、最初のインデックスに field="name" が含まれている必要があると予想される場合、コードは重複するエントリを含む配列になります。また、2 回目に _append に呼び出される data の値には、値「name」を持つプロパティ「field」が含まれています。関数を初めて呼び出したときから、引数のスコープに残っているように見えますか? これはどのように可能ですか。引数のスコープが 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

いくつかの調査の後、Adobe Coldfusionドキュメントページでこれを見つけました(テキストの太字は私が行いました):

Arguments スコープについて

すべての関数引数は、Arguments スコープという独自のスコープに存在します。Arguments スコープは、関数呼び出しの存続期間中存在します。関数が戻ると、スコープとその変数は破棄されます。ただし、Argument スコープを破棄しても、ColdFusion が参照によって関数に渡す構造体やクエリ オブジェクトなどの変数は破棄されません。関数の引数として使用する呼び出しページの変数は引き続き存在します。関数が引数の値を変更すると、呼び出しページの変数は変更された値を反映します

これは私にとって目を見張るものでした。これは、将来私をトラブルから守ります:)

于 2017-12-15T11:43:04.567 に答える