diff --git a/src/Angular.js b/src/Angular.js index d1d4d70f3b31..6523fdd4e811 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -245,8 +245,11 @@ function forEach(obj, iterator, context) { } } } else if (isArray(obj) || isArrayLike(obj)) { + var isPrimitive = typeof obj !== 'object'; for (key = 0, length = obj.length; key < length; key++) { - iterator.call(context, obj[key], key); + if (isPrimitive || key in obj) { + iterator.call(context, obj[key], key); + } } } else if (obj.forEach && obj.forEach !== forEach) { obj.forEach(iterator, context); diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 01d6f5eb7086..e310c261b5a4 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -650,6 +650,16 @@ describe('angular', function() { forEach(obj, function(value, key) { log.push(key + ':' + value); }); expect(log).toEqual(['length:2', 'foo:bar']); }); + + + it('should not invoke the iterator for indexed properties which are not present in the collection', function() { + var log = []; + var collection = []; + collection[5] = 'SPARSE'; + forEach(collection, function (item, index) { log.push(item + index); }); + expect(log.length).toBe(1); + expect(log[0]).toBe('SPARSE5'); + }); });