Coldfusion variable scopes in CFCs
While fixing my cfTrigger framework recently, I realized that I have messed up the scopes of variables inside cfcs seriously! I omitted the var keyword for local variables and used This keyword where it should have been Variables. So before continuing to fix it, I decided to take a step back and learn again in a more proper way what variable scopes are available in Coldfusion cfcs and how to use them correctly.
There are many scopes for variables in Coldfusion such as Application, session, form, url, public, private, etc. but in this article I am only interested in the scopes related to cfcs. These include the This scope variables, Variables scope variables, variables defined with the var keyword and those defined without any keyword or scope. Keep in mind that these are considered inside a cfc context.
Findings Summary
Below is the summary of Coldfusion variable scopes related to cfcs:
| Declare with | Example | Scope | Notes |
|---|---|---|---|
| This | <cfset This.name = "khoa"> | Public | Available throughout the entire cfc and also to the caller |
| Variables | <cfset Variables.name = "khoa"> | Private to the cfc | Available throughout the entire cfc but not to the caller |
| Var | <cfset var name = "khoa"> | Private to the function | Available to the function where the declaration appears, not available to any other functions inside the cfc or the caller |
| [NOTHING] | <cfset name = "khoa"> | Same as Variables | This is essentially the same as using the Variables scope. So it's better to explicitly write the Variables scope to avoid confusion |
Example
Due to the example file being a little bit long, I won't post it here. But please download them at the end of this article to test them out yourself. In the example, I have a Person class (person.cfc) that has a number of local variables, VARIABLES (cfc) variables, THIS variables and some declared without any scope or keyword. I then use a cfm file to display them to show you which ones are available at which scopes. Download and open the files and read on to see my explanation of the example.
What I did in the example:
-
Call a function to display the Variables scope variables from inside the object. This returns:
- Variables that are defined with the explicit Variables scope, and
- Variables that are defined without using any scope
This happens regardless of where the variables are defined: in the same function, in another function or at the top of the cfc outside all functions.
-
Call a function to display the This scope variables from inside the object. This returns:
- Variables that are defined with the explicit This scope
Again, this happens regardless of where the variables are defined.
-
Display the list of variables available to the caller from outside the object. This returns:
- Variables that are defined with the explicit This scope
This is the same list of variables as in the second call above.
Notes: I only display the simple values in this example. If you dump the Variables or This scope, you will have much more such as other variable types and function definitions.
Takeaways
- Always declare local variables with the var keyword, or you will (very likely) receive unexpected results
- Use VARIABLES scope to store variables that you want to be shared, available, across the entire cfc. This is especially useful in the init method, where you initialize the object and would like to store some object properties for later use.
- Use scope (or the var keyword) when declaring variables inside cfc to keep them organized and avoid variables appearing where you don't expect them. Without a scope, it will default to the VARIABLES scope. So it's always good to explicitly give it a scope.
- In Coldfusion, This is public while it is generally private in most other languages. And as in any other languages, try to limit the number of public variables. Only expose as much as you need to. That means limit the use of This.
5 Comments
-
John Barnes15 Sep 2010, 5:08 AM
You could also mention the explicit local scope in CF9. So you can now do
<cfset local.name = 'johnny' />
Which is private to the function, I find it cleaner and more logical than using the var scope.
-
Vinh Khoa Nguyen15 Sep 2010, 6:23 AM
@Stephen, I tested this against CF8 and Railo 3.1
@Johnny, that is great news! I haven't tried out CF9 yet so I'm not aware of that scope. When using CF8, I always wish there is such a scope for local variables so that I could cfdump and see all the local variables at once. Thanks for letting me know :-) It is definitely cleaner, can't wait for it to come to Railo. -
Unibands11 May 2011, 12:03 PM
@Vinh Khoa Nguyen
If you want to recreate this type of behaviour in earlier versions, here's a workaround:
At the top of the cffunction create ONE var variable called 'local' that creates a structure.
<cfset var local = {} />
Now you can create variables on the fly which are simply stored in this structure like:
<cfquery name="local.myQuery">
...
</cfquery>The beauty of this, is that if you ever upgrade to CF9+ then you can just remove the first line that declares your structure and everything will still work the same.
Mikey.
-
Vinh Khoa Nguyen11 May 2011, 8:48 PM in reply to Unibands
Interesting enough, this is exactly what I have been doing lately! The only downside is more typing as we have to keep typing local.a, local.b, etc.



Just for clarification; What version of ColdFusion Server did you test against?