Whenever you see the discourse namespace being used in this fashion in the client, it means that the method can be found in the relevant model file. In this case, you will find the
Discourse.Category.list() method in the Category model file, here.
You'll see that that method refers to the property
categories on the
Site model (
Site is a singleton - i.e. there is only ever one instance of it - and the method
currentProp is just a method that lets you get a property from a singleton model - see here).
categories property on the
Site model is kept updated from the server by a message bus subscription in an initializer - see here. This subscription subscribes to data on the server when the app initializes and gets updates when the data on the server changes.
When the categories subscription receives data, it updates the
categories property on the Site model using the
The server side of the message bus subscription is here. As you can see, it serializes (i.e. "sends one after another") the categories (i.e. "self" in the Category model) to the server as JSON.
If you want to see another example of a plugin using the message bus to push data to the client, see here in the topic ratings plugin. That publication pushes ratings data to all clients when one user adds or creates a rating.
You could use your own ajax call in this scenario if you want. However, generally it is a good idea to try and re-use as much existing core discourse infrastructure as possible. You'll save a lot of time and energy (perhaps not initially but definitely over time), you'll understand more about how Discourse works and your work will be better able to keep up with changes in the Discourse codebase.