UPDATE
Angular now offers two methods $ watchGroup (since version 1.3) and $ watchCollection . They were mentioned by @blazemonger and @kargold.
This should work regardless of types and values:
$scope.$watch('[age,name]', function () { ... }, true);
In this case, you should set the third parameter to true.
The string concatenation of 'age + name' will fail in the following case:
<button ng-init="age=42;name='foo'" ng-click="age=4;name='2foo'">click</button>
Before the user clicks the button, the observed value will be 42foo ( 42 + foo ) and after pressing 42foo ( 4 + 2foo ). Thus, the clock function will not be called. Therefore, it is better to use an array expression if you cannot guarantee that such a case does not appear.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link href="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet" /> <script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script> <script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script> <script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script> <script src="http://code.angularjs.org/1.2.0-rc.2/angular-mocks.js"></script> <script> angular.module('demo', []).controller('MainCtrl', function ($scope) { $scope.firstWatchFunctionCounter = 0; $scope.secondWatchFunctionCounter = 0; $scope.$watch('[age, name]', function () { $scope.firstWatchFunctionCounter++; }, true); $scope.$watch('age + name', function () { $scope.secondWatchFunctionCounter++; }); }); describe('Demo module', function () { beforeEach(module('demo')); describe('MainCtrl', function () { it('watch function should increment a counter', inject(function ($controller, $rootScope) { var scope = $rootScope.$new(); scope.age = 42; scope.name = 'foo'; var ctrl = $controller('MainCtrl', { '$scope': scope }); scope.$digest(); expect(scope.firstWatchFunctionCounter).toBe(1); expect(scope.secondWatchFunctionCounter).toBe(1); scope.age = 4; scope.name = '2foo'; scope.$digest(); expect(scope.firstWatchFunctionCounter).toBe(2); expect(scope.secondWatchFunctionCounter).toBe(2); </script> </head> <body></body> </html>
http://plnkr.co/edit/2DwCOftQTltWFbEDiDlA?p=preview
PS:
As pointed out by @reblace, of course, you can access the values:
$scope.$watch('[age,name]', function (newValue, oldValue) { var newAge = newValue[0]; var newName = newValue[1]; var oldAge = oldValue[0]; var oldName = oldValue[1]; }, true);