Why aren't functions used predominantly as a model for mathematics instead of set theory etc.?
Let me explain one sense in which using functions or sets provides exactly equivalent foundations of mathematics, in a way that is connected with some deep ideas in set theory. There is a translation back and forth between these foundational choices.
For example, it is a standard exercise in set theory to consider how we might construct the set-theoretic universe using characteristic functions, rather than sets, since as you noted, the characteristic function seems to provide all the necessary information about a set. We want to replace every set $A$ with a function $\chi_A$, which will have value $1$ for the "elements" of $A$ and value $0$ for objects outside $A$.
But notice that we don't really mean the ordinary elements of $A$, since we want to found the entire universe using only these functions, and so we should mean the functions that represent those elements of $A$. So this should be a recursive transfinite hereditary process.
Specifically, we can build a functional version of the set-theoretic universe as follows, in a way that perhaps fulfills the idea in your comment at the end of the first paragraph in your question. Namely, just as the set-theoretic universe is built up in a cumulative hiearchy $V_\alpha$ by iterating the power set, we can undertake a similar construction for the functional universe. We start with nothing $V_0^{\{0,1\}}=\emptyset$. If $V_\alpha^{\{0,1\}}$ is defined, then we define $V^{\{0,1\}}_{\alpha+1}$ as the set of all functions with domain contained in $V_\alpha^{\{0,1\}}$ and range contained in $\{0,1\}$. At limit stages, we take unions $V_\lambda^{\{0,1\}}=\bigcup_{\alpha<\lambda} V_\alpha^{\{0,1\}}$. The final universe $V^{\{0,1\}}$ is any function that arises in this hierarchy.
One thing to notice here is that because we allowed value $0$, we will have the same "set" being represented or named by more than one function, since $0$-values indicate non-membership. So we can define by transfinite recursion a value for equality on the names $[\![f=g]\!]$ in the natural hereditary manner: the value will be $1$, if the "members" of $f$ and $g$ are also equivalent with value $1$. And we can define the truth value of the membership relation $[\![f\in g]\!]$, which will be $1$ if $f$ is equivalent to some $f'$ for which $g(f')=1$. Meanwhile, every object $a$ in the original set-theoretic universe has a canonical name $\check a$, which is the constant $1$ function on the collection $\{\check b\mid b\in a\}$.
You can extend the truth value assignments to all assertions in the language of set theory $[\![\varphi]\!]$, and the fundamental fact to prove for this particular way of undertaking the functional universe construction is that a set-theoretic statement is true in the original set-theoretic universe if and only if the value of the statement on the corresponding names is $1$. $$V\models\varphi[a]\quad\iff\quad [\![\varphi(\check a)]\!]=1.$$ The truth values on the right are all about the functional universe $V^{\{0,1\}}$, and this equivalence expresses the sense in which truth in the set-theoretic universe is exactly copied over to the functional universe.
Conversely, given any functional universe, one can extract a corresponding set-theoretic universe. So the two approaches are essentially equivalent, the set-theoretic universe or the characteristic-functional universe.
A further thing to notice next is that the functional approach to foundations opens up an intriguing possibility. Namely, although we had used truth values $\{0,1\}$, which amounts to using classical logic, suppose that we had used another logic?
For example, if we had used functions into $\newcommand\B{\mathbb{B}}\B$, a complete Boolean algebra, then we would have constructed the universe $V^{\B}$ of $\B$-valued sets, which are hereditary functions into $\B$.
Set-theorists will recognize this as the core of the forcing method, for the elements of $V^{\B}$ are precisely the $\B$-names commonly considered in forcing. The main point is that
Forcing is the method of using a functional foundations, but where one uses a complete Boolean algebra $\B$ in place of the classical logic $\{0,1\}$.
The amazing thing about forcing is that it turns out that for any complete Boolean algebra $\B$, the ZFC axioms still come out fully true, so that $[\![\varphi]\!]=1$ for any axiom $\varphi$ of ZFC. But meanwhile, other set-theoretic statements such as the continuum hypothesis or what have you, can get value $0$ or intermediate values. This is how one establishes independence results in set theory.
I find it remarkable, a profound truth about mathematical foundations, that the nature of set-theoretic truth, concerning the continuum hypothesis or other set-theoretic statements, simply flows out of the choice of which logic of truth values to have when you are building the set-theoretic universe.
Finally, let me mention that one can undertake exactly the same process using other algebras of truth values, which are not necessarily Boolean algebras. For example, using a Heyting algebra gives rise to topos theory. And using paraconsistent logics, such as the three-element logic, gives rise to paraconsistent set theory.
Von Neumann (1925, 1928) proposed a foundation for mathematics with function as the primitive concept. And in his version, sets were defined as certain functions.
Later, logicians found that there was an equivalent way of doing what von Neumann did, but with sets and classes as primitives. Today we call it NBG, attributing it to von Neumann, Bernays, and Goedel.
I would argue that functions are indeed used as a model for some parts of mathematics, and that their roles may perhaps increase in the next century so as to account for a large part of the foundation of mathematicians work.
It is true that at the start of XX century, there was a big hope that set theory may provide a unifying framework to the whole of mathematics. This predominant position is perhaps less clear nowadays. It has been challenged by category theory on one hand. You may say that arrows are an abstraction for the concept of functions. These arrows have to map objects to objects, so there is still a need for an abstraction to sets.
But that's not what I want to argue here. I think that the real challenge is coming from a part of mathematics that has since taken its own independence, namely theoretical computer science. The concept of computation can be defined in term of a Turing machine or using the $\lambda$-calculus of A. Church. That last approach uses only functions and has given rise to functional programming, a paradigm gaining increasing attention both from computer scientists, programmers and mathematicians.
If mathematics take a slightly more algorithmical viewpoint in the future, e.g. because of a continuous stream of interesting problems from the computer sciences, then a better understanding of the foundations of computation may be needed, which in turns will change the way we do mathematics. I am thinking particularly of the work of Voevodsky concerning the univalent foundations of mathematics, which revisits a part of mathematics deeply connected with set theory and category theory, namely algebraic topology. These univalent foundations are deeply connected to computer science. Combined with the Martin-Löf type theory, they provide a practical system for formalization of modern mathematics. A large amount of mathematics has been formalized using this system and modern proof assistants such as Coq and Agda. Coq has been written in Ocaml, a functional langage, so that functions and the $\lambda$-calculus are playing a very concrete role in this reformulation of mathematics. So concrete that you can run it on your computer. As far as I understand, types play the role of sets or objects in ZFC or category theory. This is recent mathematical work and I am certainly not the most qualified to talk about this. An entry point is the 2014 Bourbaki seminar of T. Coquand in french or the slides of Voevodsky.