this is a hard question to answer well. in general, locals refer to temporary registers. when you declare a local function or table, you'll allocate a new object (in the heap), then place a pointer to it in the temporary register associated with the local. when that local goes out of scope, the table will be considered collectable by the GC, provided there are no other references to it.
numbers are different -- they're just stored directly in the register; there's no heap allocation. strings are also different -- Lua maintains a string pool shared across the entire state. thus when, exactly, a new string will be allocated or freed can be hard to predict. for example, if you have a unique string literal in your code, it get's allocated at parse time (not run time).
the next level of complication is upvalue semantics -- as an object that's declared as a local, but then captured as a upvalue, can survive outside of it's scope. upvalue catching is conservative though, so, in a situation like this:
return function() return a.f end
tables b and c will be collectable as soon as they go out of scope, but table a will live on until the returned closure gets freed.
So going out of scope, pops out the variable referring to the object on heap, and if object has no other reference, then it is queued for GC. Is that the right understanding ?
so, yes, this is pretty much right. unless the object in question is a string literal.