Here's how I would do it. Since you're making something backwards compatible with CF8, which does not explicitly have the 'Local' scope, and you've already declared it via the 'var', then we'll put all other function local variables within this struct, and only return that which is needed.
* FUNCTION toKeyValuePairArray
* Method to create a simple object reference array to reduce overhead and improve performance.
* This assumes that your objects have Getters for their primary properties.
* (no need to instantiate every object, every time, when all you need is a number or a name)
* @theArray (array) - an array of objects
* @idGetterFunctionName - Function name for getter function that pulls the object's id
* @valueGetterFunctionName - Function name for getter function that pulls the object's name
<cffunction name="ToKeyValuePairArray" returntype="array" output="false" access="public">
<cfargument name="theArray" type="Array" required="true" hint="an array of objects" />
<cfargument name="idGetterFunctionName" required="true" type="string" hint="Function name for getter function that pulls the object's id" />
<cfargument name="valueGetterFunctionName" required="true" type="string" hint="Function name for getter function that pulls the object's name" />
<cfset var LOCAL = StructNew() />
<cfset LOCAL.retArray = ArrayNew(1) />
<cfloop array="#ARGUMENTS.theArray#" index="LOCAL.theComponent">
<cfset LOCAL.tmpObjVals = StructNew() />
<cfinvoke component="#LOCAL.theComponent#" method="#ARGUMENTS.idGetterFunctionName#" returnvariable="LOCAL.id" />
<cfinvoke component="#LOCAL.theComponent#" method="#ARGUMENTS.valueGetterFunctionName#" returnvariable="LOCAL.value" />
<cfset LOCAL.tmpObjVals["id"] = LOCAL.id />
<cfset LOCAL.tmpObjVals["value"] = LOCAL.value />
<cfset ArrayAppend(LOCAL.retArray,Duplicate(LOCAL.tmpObjVals)) />
<cfcatch><!--- Empty Catch ---></cfcatch>
<cfreturn LOCAL.retArray />
Since we 'var' one core variable (creating our own function local scope, so to speak) we no longer have to declare the temp object at the top of the method, since you reset it at the top of each loop iteration anyway. I also standardized your struct and array initialization across the method, to maintain that backward compatibility (and standardization of form is just good practice).
You aren't really doing any additional processing on the return variables from your 'getter' calls, so I applied them directly to the tempObj, so we don't create any unnecessary variables. You don't have to upper case scope names. I do that to make them stand out better when looking at code. I did uppercase the function names. This is just something I got from college: begin uppercase the function calls, and begin lowercase on variable names, then camel case the remainder.
NOTE: Adjusted some of my code, to work in some of Dan's (good) suggestions. I understand the 'try/catch' conceptually, but I did make them required args so it would throw errors if you didn't have them.