The problem is because of the shared scope used by the superhero directive.
The superhero directive uses the parent elements scope as its own scope because you are not using child/isolated scopes for the directive. There for both the superhero elements in your sample shares the same scope.
So first superhero creates a empty array property abilities and since it has a speed directive adds speed to it, then when the second superhero element is compiled and processed it overrides this property again with a empty array because both of them works in the same scope
var app = angular.module('myApp', []);
app.directive('superhero', function () {
return {
restrict: 'E',
scope: true,
controller: function ($scope) {
$scope.abilities = [];
this.addStrength = function () {
console.log('adding strength', $scope.$id);
$scope.abilities.push('strength');
console.log($scope.abilities);
}
this.addSpeed = function () {
console.log('adding speed', $scope.$id);
$scope.abilities.push('speed');
console.log($scope.abilities);
}
},
link: function (scope, element) {
console.log('link', scope.$id, scope.abilities)
element.bind('mouseenter', function () {
console.log('me', scope.$id, scope.abilities)
})
}
}
})
Demo: Fiddle