Por que não usar o this em JavaScript

Pessoas acostumadas a linguagens como Java têm problemas para compreender a palavra-chave this em Javascript. Uma das características loucas e insanas (e definitivamente interessantes) do JavaScript é que a palavra-chave this em uma função pode ser sobrescrita por quem quer que chame a função. Desse modo, o this dentro e fora de uma função pode se referir a dois objetos ou escopos totalmente diferentes.
Sendo assim, em geral, é melhor atribuir a referência this em um controlador a uma variável proxy e sempre referenciar a instância por meio desse proxy (self, por exemplo) para garantir que a instância a que estamos nos referindo seja a instância correta.
Se quiser saber mais sobre esse assunto bem como entender um pouco mais sobre a loucura que pode ser o JavaScript, dê uma olhada no livro You Don’t Know JS: this & Object Prototypes (O’Relly, 2014) de Kyle Simpson.

Referência:
Desenvolvendo com AngularJS
Aumento de Produtividade com Aplicações Web Estruturadas

AngularJS – Using $resource for Data Models

<!doctype html>
<html ng-app="app">
<head>
  <meta charset="utf-8">
  <title>AngularJS test</title>
 
  <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="styles/styles.css">
 
 
</head>
<body>
  <div ng-controller="MainCtrl">
    <div class="container">
      <h1 ng-show="posts.length">Posts</h1>
      <table class="table table-striped" ng-show="posts.length">
        <thead>
          <th>Title</th>
        </thead>
        <tbody>
        <tr ng-repeat="post in posts">
          <td ng-click="activePost(post)">{{post.title}}</td>
          <td><button class="btn btn-danger" ng-click="delete(post)">Delete</button></td>
        </tr>
        </tbody>
      </table>
      <h3 ng-if="!editing">New Post</h3>
      <h3 ng-if="editing">Edit Post</h3>
      <form ng-submit="save(post)">
        <input ng-model="post.title">
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
        <button ng-if="editing" class="btn btn-success" ng-click="newPost()">New Post</button>
    </div>
  </div>
  <script src="../angular/angular.min.js"></script>
  <script src="../angular-resource/angular-resource.min.js"></script>
  <script src="../angular-route/angular-route.min.js"></script>
 
  <script src="../lodash/dist/lodash.js"></script>
  <script src="scripts/app.js"></script>
  <script src="scripts/models/post.js"></script>
  <script src="scripts/controllers/main.js"></script>
</body>
</html>

controllers/main.js

angular.module('app')
  .controller('MainCtrl', ['$scope', '$route', 'Post',
      function($scope, $route, Post) {
 
        $scope.post = new Post();
        $scope.posts = Post.query();
 
        $scope.newPost    = function() {
          $scope.post = new Post();
          $scope.editing = false;
        }
 
        $scope.activePost = function(post) {
          $scope.post = post;
          $scope.editing = true;
        }
 
        $scope.save = function(post) {
          if ($scope.post._id) {
            Post.update({_id: $scope.post._id}, $scope.post);
          } else {
            $scope.post.$save().then(function(response) {
              $scope.posts.push(response)
            });
          }
          $scope.editing = false;
          $scope.post = new Post();
        }
 
        $scope.delete = function(post) {
          Post.delete(post)
          _.remove($scope.posts, post)
        }
 
      }
  ]);

models/post.js

angular.module('app')
  .provider('Post', function() {
    this.$get = ['$resource', function($resource) {
      var Post = $resource('http://localhost:3000/api/post/:_id', {}, {
        update: {
          method: 'PUT'
        }
      })
 
      return Post;
    }];
  });

AngulaJS – Application Wiring: JQuery vs AngularJS

$(function () {
    $("#jquery-button").click(function () {
        $("#jquery-content").toggle();
    });
});
 
var compare = angular.module("compare", []);
compare.controller("AppCtrl", function () {
    var app = this;
 
    app.isHidden = false;
    app.toggle = function () {
        app.isHidden = !app.isHidden;
    };
});

AngularJS – Testing With Protractor Page Objects

index.spec.js

var IndexPage = require('./IndexPage');
 
describe("hello-protractor", function () {
 
  var page = new IndexPage();
 
  beforeEach(function() {
      page.get();
  });
 
  describe("index", function () {
    it("should display the correct title", function () {
      expect(page.getTitle()).toBe('hello protractor');
    });
 
    it("should display the message when button clicked", function () {
      page.clickButton();
 
      expect(page.getMessageText()).toBe('button 1 clicked');
    });
  });
});

IndexPage.js

function IndexPage() {
  this.button = element(by.id('button1'));
  this.message = element(by.binding('messageText'));
 
  this.get = function () {
    browser.get('/#');
  };
 
  this.clickButton = function () {
    this.button.click();
  };
 
  this.getTitle = function () {
    return browser.getTitle();
  };
 
  this.getMessageText = function () {
    return this.message.getText();
  }
}
 
module.exports = IndexPage;

AngularJS – $internal

var app = angular.module("app", []);
 
app.controller("AppCtrl", function ($q, $interval) {
    var timer = $interval(function () {
    }, 100, 10);
 
    function success() {
        console.log("done");
    }
 
    function error() {
        console.log("cancelled or error");
    }
 
    function notify() {
        console.log("updating");
    }
 
    timer.then(success, error, notify);
 
    this.cancel = function () {
        $interval.cancel(timer);
    };
});

AngularJS – Inject Jasmine Spies With $provide

app.js

var app = angular.module('app', []);
 
app.controller('ProfileCtrl',
    ['$scope', 'ProfileSvc',
        function ($scope,
                  profileSvc) {
 
            $scope.favoriteBooks = profileSvc
                .favoriteBooks();
 
        }]);
 
app.service('ProfileSvc', function () {
    this.favoriteBooks = function () {
        return JSON.parse(
            localStorage.getItem('favoriteBooks')
        );
    };
});

app.spec.js

describe("Providers", function () {
    var $scope,
        controller,
        profileSvcSpy,
        favoriteBooks = ["Lowside of the Road", "Life", "The Grand Pursuit"];
 
    beforeEach(module('app', function($provide) {
        profileSvcSpy = jasmine.createSpyObj("ProfileSvc", ["favoriteBooks"]);
        profileSvcSpy.favoriteBooks.andReturn(favoriteBooks);
 
        $provide.value("ProfileSvc", profileSvcSpy);
    }));
    beforeEach(inject(function($rootScope, $controller) {
        $scope = $rootScope.$new();
        controller = $controller('ProfileCtrl', {$scope: $scope});
    }));
 
    describe("Initialization", function () {
        it("Should call the profileSvc.favoriteBooks with no arguments", function () {
            expect(profileSvcSpy.favoriteBooks).toHaveBeenCalledWith();
        });
 
        it("Should set the $scope.favoriteBooks from the profileService", function () {
            expect($scope.favoriteBooks).toEqual(favoriteBooks);
        });
    });
 
});