As an array
Use an argument name that represents its use. For example, the following code is unlikely to result in confusion:
<cfscript> function SumN(Addend1,Addend2) { return Addend1 + Addend2; } </cfscript> <cfset x = 10> <cfset y = 12> <cfoutput>#SumN(x,y)#</cfoutput>
The following, similar code is more likely to result in programming errors:
<cfscript> function SumN(x,y) { return x + y; } </cfscript> <cfset x = 10> <cfset y = 12> <cfoutput>#SumN(x,y)#<cfoutput>
ColdFusion passes the following data types to the function by value:
Structures, queries, and complex objects such as COM objects are passed to UDFs by reference, so the function uses the same copy of the data as the caller. Arrays are passed to user-defined functions by value, so the function gets a new copy of the array data, and the array in the calling page is unchanged by the function. As a result, always handle arrays differently from all other complex data types.
In ColdFusion (2021 release), you can also pass arrays by reference. Set the variable this.passArrayByReference to true in Application.cfc.
For your function to modify the copy of a structure, query, or object, in the caller, pass the variable as an argument. Because the function gets a reference to the structure in the caller, the caller variable reflects all changes in the function. You do not have to return the structure to the caller. After the function returns, the calling page accesses the changed data by using the structure variable that it passed to the function.
If you do not want a function to modify the copy of a structure, query, or object, in the caller, use the Duplicate function to make a copy and pass the copy to the function.
If you want your function to modify the caller's copy of the array, the simplest solution is to pass the array to the function and return the changed array to the caller in the function return statement. In the caller, use the same variable name in the function argument and return variable.
The following example shows how to directly pass and return arrays. In this example, the doubleOneDArray function doubles the value of each element in a one-dimensional array.
<cfscript> //Initialize some variables //This creates a simple array. a=ArrayNew(1); a[1]=2; a[2]=22; //Define the function. function doubleOneDArray(OneDArray) { var i = 0; for ( i = 1; i LE arrayLen(OneDArray); i = i + 1) { OneDArray[i] = OneDArray[i] * 2; } return OneDArray; } //Call the function. a = doubleOneDArray(a); </cfscript> <cfdump var="#a#">
This solution is simple, but it is not always optimal:
<cfscript> //Initialize some variables. //This creates a simple array as an element in a structure. arrayStruct=StructNew(); arrayStruct.Array=ArrayNew(1); arrayStruct.Array[1]=2; arrayStruct.Array[2]=22; //Define the function. function doubleOneDArrayS(OneDArrayStruct) { var i = 0; for ( i = 1; i LE arrayLen(OneDArrayStruct.Array); i = i + 1) { OneDArrayStruct.Array[i] = OneDArrayStruct.Array[i] * 2; } return True; } //Call the function. Status = doubleOneDArrayS(arrayStruct); WriteOutput("Status: " & Status); </cfscript> </br> <cfdump var="#arrayStruct#">
Use the same structure element name for the array (in this case Array) in the calling page and the function.
All function arguments exist in their own scope, the Arguments scope.
The Arguments scope exists for the life of a function call. When the function returns, the scope and its variables are destroyed.
However, destroying the Argument scope does not destroy variables, such as structures or query objects, that ColdFusion passes to the function by reference. The variables on the calling page that you use as function arguments continue to exist; if the function changes the argument value, the variable in the calling page reflects the changed value.
The Arguments scope is special, in that you can treat the scope as either an array or a structure. This dual nature of the Arguments scope is useful because it makes it easy to use arguments in any of the following circumstances:
The following rules apply to the Arguments scope and its contents:
<cffunction name="TestFunction"> <cfargument name="Arg1"> <cfargument name="Arg2"> </cffunction>
You can call this function with a single argument, as in the following line:
<cfset TestFunction(1)>
The resulting Arguments scope looks like the following:
As an array |
|
As a structure |
|
---|---|---|---|
Entry |
Value |
Entry |
Value |
1 |
1 |
Arg1 |
1 |
2 |
undefined |
Arg2 |
undefined |
In this example, the following functions return the value 2 because the scope contains two defined arguments:
ArrayLen(Arguments) StructCount(Arguments)
However, the following tests return the value false, because the contents of the second element in the Arguments scope is undefined.
Isdefined("Arguments.Arg2") testArg2 = Arguments[2]> Isdefined("testArg2")
The IsDefined function does not test the existence of array elements. Use the function ArrayContains to search the array elements.
The following rules apply to referencing Arguments scope as an array:
<cffunction name="TestFunction" > <cfargument name="Arg1"> <cfargument name="Arg2"> <cfloop index="i" from="1" to="#ArrayLen(Arguments)#"> <cfoutput>Argument #i#: #Arguments[i]#<br></cfoutput> </cfloop> </cffunction> <strong>One Unnamed argument</strong><br> <cfset TestFunction(1)> <strong>Two Unnamed arguments</strong><br> <cfset TestFunction(1, 2)> <strong>Three Unnamed arguments</strong><br> <cfset TestFunction(1, 2, 3)> <strong>Arg1:</strong><br> <cfset TestFunction(Arg1=8)> <strong>Arg2:</strong><br> <cfset TestFunction(Arg2=9)> <strong>Arg1=8, Arg2=9:</strong><br> <cfset TestFunction(Arg1=8, Arg2=9)> <strong>Arg2=6, Arg1=7</strong><br> <cfset TestFunction(Arg2=6, Arg1=7)> <strong>Arg1=8, Arg2=9, Arg3=10:</strong><br> <cfset TestFunction(Arg1=8, Arg2=9, Arg3=10)> <strong>Arg2=6, Arg3=99, Arg1=7</strong><br> <cfset TestFunction(Arg2=6, Arg3=99, Arg1=7)>
Although you can use the Arguments scope as an array, the IsArray(Arguments) function always returns false and the cfdump tag displays the scope as a structure.
The following rule applies when referencing Arguments scope as a structure:
A function can have optional arguments that you do not have to specify when you call the function. To determine the number of arguments passed to the function, use the following function:
ArrayLen(Arguments)
When you define a function using CFScript, the function must use the Arguments scope to retrieve the optional arguments. For example, the following SumN function adds two or more numbers together. It requires two arguments and supports any number of additional optional arguments. You can reference the first two, required, arguments as Arg1 and Arg2 or as Arguments1 and Arguments2. Access the third, fourth, and any additional optional arguments as Arguments3, Arguments4, and so on
function SumN(Arg1,Arg2) { var arg_count = ArrayLen(Arguments); var sum = 0; var i = 0; for( i = 1 ; i LTE arg_count; i = i + 1 ) { sum = sum + Arguments[i]; } return sum; }
With this function, any of the following function calls are valid:
SumN(Value1, Value2) SumN(Value1, Value2, Value3) SumN(Value1, Value2, Value3, Value4)
and so on.
The code never uses the Arg1 and Arg2 argument variables directly, because their values are always the first two elements in the Arguments array and it is simpler to step through the array. Specifying Arg1 and Arg2 in the function definition ensures that ColdFusion generates an error if you pass the function one or no arguments.
Avoid referring to a required argument in the body of a function by both the argument name and its place in the Arguments scope array or structure, as doing so can be confusing and makes it easier to introduce errors.
When you define a function using the cffunction tag, you generally reference the arguments directly by name if all arguments are named in the cfargument tags. If you do use the Arguments scope identifier, follow the rules listed in About the Arguments scope.
For more information on using the Arguments scope in functions defined using CFScript, see Using the Arguments scope in CFScript.
In addition to the Arguments scope, each function can have variables that exist only inside the function, and are not saved between times the function gets called. As soon as the function exits, all the variables in this scope are removed.
In CFScript, you create function-only variables with the var statement. Unlike other variables, you never prefix function-only variables with a scope name.
Make sure to use the var statement in CFScript UDFs to declare all function-specific variables, such as loop indexes and temporary variables that are required only for the duration of the function call. Doing so ensures that these variables are available inside the function only, and makes sure that the variable names do not conflict with the names of variables in other scopes. If the calling page has variables of the same name, the two variables are independent and do not affect each other.
For example, if a ColdFusion page has a cfloop tag with an index variable i , and the tag body calls a CFScript UDF that also has a loop with a function-only index variable i , the UDF does not change the value of the calling page loop index, and the calling page does not change the UDF index. So you can safely call the function inside the cfloop tag body.
In general, use the var statement to declare all UDF variables, other than the function arguments or shared-scope variables, that you use only inside CFScript functions. Use another scope, however, if the value of the variable must persist between function calls; for example, for a counter that the function increments each time it is called.
A function can use and change any variable that is available in the calling page, including variables in the caller's Variables (local) scope, as if the function was part of the calling page. For example, if you know that the calling page has a local variable called Customer_name (and no function scope variable named Customer_name exists) the function can read and change the variable by referring to it as Customer_name or (using better coding practice) Variables.Customer_name. Similarly, you can create a local variable inside a function and then use it anywhere in the calling page after the function call. You cannot use the variable before you call the function.
However, generally avoid using the caller's variables directly inside a function. Using the caller's variables creates a dependency on the caller. Ensure that the code outside the function uses the same variable names as the function. Doing so can become difficult if you call the function from many pages.
You can avoid these problems by using only the function arguments and the return value to pass data between the caller and the function. Do not reference calling page variables directly in the function. As a result, you can use the function anywhere in an application (or even in multiple applications), without concern for the calling code variables.
As with other programming practices, valid exceptions to this recommendation exist. For example, you can do any of the following:
If your function must directly change a simple variable in the caller (one that is not passed to the function by reference), you can place the variable inside a structure argument.
Function arguments can have the same names, but different values, as variables in the caller. Avoid such uses for clarity, however.
The following rules apply to argument persistence:
If a function must use a variable from another scope that has the same name as a function-only variable, prefix the external variable with its scope identifier, such as Variables or Form. (However, remember that using variables from other scopes directly in your code is often poor practice.)
Bei Ihrem Konto anmelden