5

何を言っているのかわからない場合は、次のことを試してください。

<cffunction name="myFunc">
    <cfargument name="myArg" default="foobar">
    <cfdump var="#local#" label="local and arguments scopes before deleting myArg">
    <cfset StructDelete(arguments, "myArg")>
    <cfdump var="#local#" label="local and arguments scopes after deleting myArg">
    <cfset StructDelete(local, "arguments")>
    <cfdump var="#local#" label="local scope after deleting arguments scope">
    <cftry>
        <cfset writeOutput("myArg still exists, and evaluates to: " & myArg)>
        <cfcatch>
            <cfset writeOutput("myArg no longer exists")>
        </cfcatch>
    </cftry>
</cffunction>

<cfset myFunc()>

<cfexit>

そのコードを実行すると、引数と引数のスコープの両方を削除した後でも、宣言された引数にスコープなし参照を介してアクセスできることがわかります。これは、宣言された引数のコピーまたはその値への参照を含む名前のないスコープがあることを意味します。私が見つけようとしているのは、文書化されていないスコープ名や、基礎となる Java の getter メソッドなど、このスコープを直接操作する方法があるかどうかです。今のところ、これは純粋に学問的な質問だと考えてください。なぜなら、私が考えているユースケースは、ほとんどの評判の良いプログラマーによって手に負えないほど却下されると確信しているためです。

編集

Adam の回答は境界線をぼやけさせているので、UDF スコープに関する私の現在の理解の内訳を提供することは有益かもしれないと考えました。簡単にするために、cfc 固有のものは除外します...

  • スコープまたは「var」キーワードなしで定義された変数は、呼び出しページの変数スコープに配置されます。

  • ローカルスコープには、関数の実行中にvarキーワードまたはローカルスコープ名 (例: local.myvar、local["myvar"])を使用して作成される変数が含まれます。また、引数のスコープも含まれています。

  • 引数スコープには、関数呼び出しで宣言または渡されるすべての引数が含まれます。関数の実行中に変数を追加または削除することもできます。引数スコープはローカル スコープのメンバーであり、ローカルスコープとして参照できます (例: local.arguments.myvar、local.arguments[1]) が、独立して参照することもできます (例: arguments.myvar、arguments[1])。 .

  • 宣言されているすべての引数の複製を含む名前のないスコープがあります(つまり、cfargument タグに含まれているか、cfscript の関数定義の先頭にある括弧に含まれています)。このスコープに関連する次の特徴と動作を観察しました。

    • 宣言されていない引数は、名前のないスコープに追加されません。

    • 引数を宣言することは、変数を名前のないスコープに入れる唯一の方法であり、ColdFusion はそれを他の状況では使用しないようです。

    • 引数のスコープとは異なり、名前のないスコープにはローカルスコープとの明確な関係はありません。

    • 名前のないスコープの変数とその対応する引数のスコープの値は、同じ値への参照であるか、一方を変更すると両方が変更されるような方法で相互に接続されています。

    • 新しい変数を引数に動的に追加しても、名前のないスコープには追加されません(宣言された引数のみが名前のないスコープに追加されるため)。

    • 名前のないスコープの変数は、従来の方法 (つまり、StructDelete()、ArrayDeleteAt()) では削除できません。対応するスコープの引数を削除できますが、値はスコープ外の参照を介して引き続き使用できます。(宣言された引数を完全に削除する方法については、ヘンリーの回答を参照してください)。

    • 宣言された引数が arguments から削除される、名前のないスコープの対応する値を個別に設定できます。これは、同じ名前の変数が引数に追加された場合でも当てはまります。

    • CF9 と CF10 には名前のないスコープが存在しますが、(Henry と Adam が指摘したように) Railo にはありません。

    • 名前のないスコープは、CF のスコープ階層の絶対的な最上位にあり、スコープのない参照が使用されている場合、他のすべてのスコープよりも優先されます。これは、以前の削除不能性に関するポイントとともに、名前のないスコープについて知っておくべき最も重要なことです。公式ドキュメントとは異なり、関数固有のスコープ階層は次のようになります。

      1. nameless (宣言された引数)
      2. ローカル
      3. 引数
4

2 に答える 2

1

興味深いことに、このテスト ケースには非常に奇妙な動作があります。myArgなぜまだ利用できるのかわかりません。ただし、変数をスコープしてこれを行う場合:

<cfset writeOutput("myArg still exists, and evaluates to: " & arguments.myArg)>

または、の代わりにstructDelete()、次のように設定した場合null:

<cfset myArg = javacast("null","")>

それからあなたは得るでしょう"myArg no longer exists"

これは、Adobe CF の最適化のエッジ ケースである可能性があります。Railo は期待どおりに実行され、期待どおりの結果が得られます。http://cflive.net/で自分でテストできます。

于 2013-09-11T01:15:35.920 に答える