Le recomiendo que lea la documentación oficial en profundidad de Angular para los ámbitos. Empiece en la sección 'Jerarquías de ámbito':
https://docs.angularjs.org/guide/scope
Básicamente, $ rootScope y $ scope identifican partes específicas del DOM dentro de las cuales
- Se realizan operaciones angulares
- las variables declaradas como parte de $ rootScope o $ scope están disponibles
Todo lo que pertenezca a $ rootScope está disponible globalmente en su aplicación Angular, mientras que cualquier cosa que pertenezca a $ scope está disponible dentro de la parte del DOM a la que se aplica ese alcance.
$ RootScope se aplica al elemento DOM que es el elemento raíz de la aplicación Angular (de ahí el nombre $ rootScope). Cuando agrega la directiva ng-app a un elemento del DOM, este se convierte en el elemento raíz del DOM dentro del cual $ rootScope está disponible. En otras palabras, las propiedades, etc. de $ rootScope estarán disponibles en toda su aplicación Angular.
Un alcance $ angular (y todas sus variables y operaciones) está disponible para un subconjunto particular del DOM dentro de su aplicación. Específicamente, el alcance $ para cualquier controlador en particular está disponible para la parte del DOM a la que se ha aplicado ese controlador en particular (usando la directiva ng-controller). Sin embargo, tenga en cuenta que ciertas directivas, por ejemplo, ng-repeat, cuando se aplican dentro de una parte del DOM donde se ha aplicado el controlador, pueden crear ámbitos secundarios del ámbito principal, dentro del mismo controlador, un controlador no necesariamente contiene solo un ámbito.
Si observa el HTML generado cuando ejecuta su aplicación Angular, puede ver fácilmente qué elementos DOM 'contienen' un alcance, ya que Angular agrega la clase ng-scope en cualquier elemento al que se haya aplicado un alcance (incluido el elemento raíz de la aplicación, que tiene $ rootScope).
Por cierto, el signo '$' al comienzo de $ scope y $ rootScope es simplemente un identificador en Angular para cosas reservadas por Angular.
Tenga en cuenta que el uso de $ rootScope para compartir variables, etc. entre módulos y controladores no suele considerarse una práctica recomendada. Los desarrolladores de JavaScript hablan de evitar la 'contaminación' del alcance global compartiendo variables allí, ya que puede haber conflictos más adelante si se usa una variable del mismo nombre en otro lugar, sin que el desarrollador se dé cuenta de que ya está declarada en $ rootScope. La importancia de esto aumenta con el tamaño de la aplicación y el equipo que la desarrolla. Idealmente, $ rootScope solo contendrá constantes o variables estáticas, que deben ser consistentes en todo momento en toda la aplicación. Una mejor manera de compartir cosas entre módulos puede ser utilizar servicios y fábricas, ¡que es otro tema!