Just for the heck of it, I tracked this down in the jQuery code. The .val() function currently starts at line 165 of attributes.js. Here's the relevant section, with my annotations:
val: function( value ) {
    var hooks, ret, isFunction,
        elem = this[0];
        /// NO ARGUMENTS, BECAUSE NOT SETTING VALUE
    if ( !arguments.length ) {
        /// IF NOT DEFINED, THIS BLOCK IS NOT ENTERED. HENCE 'UNDEFINED'
        if ( elem ) {
            hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                return ret;
            }
            ret = elem.value;
            /// IF IS DEFINED, JQUERY WILL CHECK TYPE AND RETURN APPROPRIATE 'EMPTY' VALUE
            return typeof ret === "string" ?
                // handle most common string cases
                ret.replace(rreturn, "") :
                // handle cases where value is null/undef or number
                ret == null ? "" : ret;
        }
        return;
    }
So, you'll either get undefined or "" or null -- all of which evaluate as false in if statements.