Some confusion about what a function "really is".
There are two common "general" definitions for functions in modern mathematics:
A function is a set (or class) of ordered pairs with a particular property: if $(x,y)$ and $(x,z)$ both belong to the function, then $y=z$.
A function is an ordered triplet, $(A,B,f)$ with $f$ being a set of ordered pairs as the previous definition goes, with domain $A$ and range a subset of $B$.
(There can be other definitions, depending on the context.)
These definitions are not "an oversimplification that teachers used in high school", and certainly not something to "grow out of" past calculus. In fact, in most high schools, a student is likely to believe that a function is always given by some sort of formula, whereas in both of these abstract definitions no formula is needed, and in many cases, one cannot even assume there is a formula in the meta-language which defines the graph of the function.
There is no reason to be disappointed by this formalization any more than there is to be disappointed by the implementation of "integer" as a number in a finite range (such as $-2^{31}$ to $2^{31}-1$) when it comes to programming in C. Functions, as well as integers in C, are useful to us and their formalization works out just fine; and whenever we reach some limitations of these formalizations we can bypass them (with class functions in set theory, and with bignum libraries in C, often limited mostly by available memory).
There are two good reasons not to think of functions in terms of "properties":
When formalizing mathematics, one can show that in general one should not expect every mathematical object to have "expressible properties". Namely, given the real numbers, and any "naively reasonable naming mechanism" there will be real numbers which cannot be named. So if we cannot expect every real number to have a discerning property, why should we expect more complicated objects to have them?
The point of set theory as a foundational theory is to implement mathematics at a semantic level. Namely, interpret objects as sets. Having a very simple definition for a set (in a technical sense of "very simple") is a good thing, and it allows the foundations to carry all sort of theorems. For example, when talking about sufficiently simple statements about the natural numbers, one can omit the axiom of choice from the assumptions.
One of the reasons this can be done is that our interpretation of "function" is sufficiently simple that we can be certain it does not change between our original universe, and an inner universe where the axiom of choice holds. That way we can ensure that if the statement was true in the inner universe, it will remain true in our universe as well. Of course, one could perhaps formalize similar theorems for however you wish to encode functions into sets, but the more complicated the coding mechanism becomes, the more fragile our theorems become, and it gets harder to prove them.
So simplicity has its benefits when it comes to actually proving things from a foundational point of view.
How you view a function depends on what you want to do with that function. If set theory is your foundation then functions are modeled as being pairs of elements between the elements of the domain and that elements image in the codomian.
However in type theories a function is treated as a fundamental thing that can't be simplified. We simply describe how functions map between types via lambda calculus.
In category theory the fact that function map elements becomes of less importance as a functions behaviour as it is composed with other functions becomes more important.
In general, mathematicians aren't so interested in what things are, more in what things do. A function is a thing that you can apply to objects to obtain other objects. It doesn't really matter if you define a function as a graph, as a triplet (domain, codomain, graph), a first-class object, or something else entirely - it still represents the same abstract concept. (Assuming the definition supports this concept, of course).
Once you establish the basic properties of functions, you can pretty much forget the definition. Just like I know that 4+5=9 without caring if I defined natural numbers as sets of all smaller natural numbers, or something else.
Personally I find the definition as a graph more elegant than the triplet definition. Specifying the domain is unnecessary since it is uniquely obtainable from the graph. Specifying the codomain does add some information, but this extra information is often irrelevant. Not to mention that triplets are by themselves messy to define.
Even with the graph definition, the function is still "a mathematical object in its own right". The collection of all values it gives to all inputs is an abstraction that transcends any single value it takes.