fn(){ printf %s\\n "${v-not set}"; }
v=value; fn; unset v; fn
value
not set
A shell function is a literal string stored in the shell's memory. At define time it is parsed, but is not evaluated for expansions (other than shell aliases) or redirections. These are only evaluated at call time.
In fact, and somewhat related, in this way it is possible to get a function to define its own input with a new temporary file at each invocation.
fn(){ ls -l /dev/fd/0; cat; } <<INFILE
$@
INFILE
fn some args; fn other args
#in dash
lr-x------ 1 mikeserv mikeserv 64 Nov 16 12:50 /dev/fd/0 -> pipe:[4076148]
some args
lr-x------ 1 mikeserv mikeserv 64 Nov 16 12:50 /dev/fd/0 -> pipe:[4077081]
other args
#bash
lr-x------ 1 mikeserv mikeserv 64 Nov 16 12:51 /dev/fd/0 -> /tmp/sh-thd-1036060995 (deleted)
some args
lr-x------ 1 mikeserv mikeserv 64 Nov 16 12:51 /dev/fd/0 -> /tmp/sh-thd-531856742 (deleted)
other args