"¿Cómo funciona thisy $scopefunciona en los controladores AngularJS?"
Respuesta corta :
this
- Cuando se llama a la función constructora del controlador,
thises el controlador.
- Cuando
$scopese llama a una función definida en un objeto, thises el "alcance vigente cuando se llamó a la función". Esto puede (¡o no!) Ser en el $scopeque se define la función. Entonces, dentro de la función, thisy $scopepuede no ser lo mismo.
$scope
- Cada controlador tiene un
$scopeobjeto asociado .
- Una función de controlador (constructor) es responsable de establecer las propiedades del modelo y las funciones / comportamiento en sus asociados
$scope.
- Solo los métodos definidos en este
$scopeobjeto (y los objetos del ámbito principal, si la herencia prototípica está en juego) son accesibles desde la vista / HTML. Por ejemplo, desde ng-click, filtros, etc.
Respuesta larga :
Una función de controlador es una función constructora de JavaScript. Cuando se ejecuta la función del constructor (por ejemplo, cuando se carga una vista), this(es decir, el "contexto de la función") se establece en el objeto controlador. Entonces, en la función del constructor del controlador "pestañas", cuando se crea la función addPane
this.addPane = function(pane) { ... }
se crea en el objeto controlador, no en $ scope. Las vistas no pueden ver la función addPane: solo tienen acceso a las funciones definidas en $ scope. En otras palabras, en el HTML, esto no funcionará:
<a ng-click="addPane(newPane)">won't work</a>
Después de que se ejecuta la función del constructor del controlador "pestañas", tenemos lo siguiente:

La línea negra discontinua indica herencia prototípica: un alcance aislado hereda prototípicamente de Scope . (No hereda prototípicamente del alcance en efecto donde se encontró la directiva en el HTML).
Ahora, la función de enlace de la directiva de panel quiere comunicarse con la directiva de pestañas (lo que realmente significa que debe afectar a las pestañas aislar $ scope de alguna manera). Se podrían usar eventos, pero otro mecanismo es hacer que el panel dirija requireel controlador de pestañas. (Parece que no hay ningún mecanismo para la directiva de panel para requirelas pestañas $ scope).
Entonces, esto plantea la pregunta: si solo tenemos acceso al controlador de pestañas, ¿cómo podemos acceder a las pestañas aislar $ scope (que es lo que realmente queremos)?
Bueno, la línea punteada roja es la respuesta. El "alcance" de la función addPane () (me refiero al alcance / cierres de la función de JavaScript aquí) le da a la función acceso a las pestañas aislar $ scope. Es decir, addPane () tiene acceso a las "pestañas IsolateScope" en el diagrama anterior debido a un cierre que se creó cuando se definió addPane (). (Si en su lugar definimos addPane () en el objeto de pestañas $ scope, la directiva de panel no tendría acceso a esta función y, por lo tanto, no tendría forma de comunicarse con las pestañas $ scope).
Para responder la otra parte de su pregunta how does $scope work in controllers?:
Dentro de las funciones definidas en $ scope, thisse establece en "el alcance de $ vigente donde / cuando se llamó a la función". Supongamos que tenemos el siguiente HTML:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
Y el ParentCtrl(Solamente) tiene
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Al hacer clic en el primer enlace se mostrará eso thisy $scopeson lo mismo, ya que " el alcance en vigor cuando se llamó a la función " es el alcance asociado con el ParentCtrl.
Al hacer clic en el segundo enlace se revelará thisy no$scope es lo mismo, ya que " el alcance en vigor cuando se llamó a la función " es el alcance asociado con el ChildCtrl. Así que aquí, thisse establece en ChildCtrl's $scope. Dentro del método, $scopesigue siendo el ParentCtrlalcance de $.
Violín
Intento no usar thisdentro de una función definida en $ scope, ya que se vuelve confuso qué $ scope está siendo afectado, especialmente teniendo en cuenta que ng-repeat, ng-include, ng-switch y directivas pueden crear sus propios ámbitos secundarios.