From 68010747cb54799914dd804bf7b88ee4d5a327bc Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 7 Aug 2014 10:13:01 -0400 Subject: [PATCH] fix(forEach): match behaviour of Array.prototype.forEach (ignore missing properties) Array.prototype.forEach will not invoke the callback function if the properety is not present in the object. Because of this, we have the illusion of not iterating over non-added properties in a sparse array. From ECMAScript: 9. Repeat while k < len a. Let Pk be ToString(k). b. Let kPresent be HasProperty(O, Pk). c. ReturnIfAbrupt(kPresent). d. If kPresent is true, then i. Let kValue be Get(O, Pk) ... (steps for invoking the function and aborting if it throws) Closes #8510 Closes #8522 --- src/Angular.js | 5 ++++- test/AngularSpec.js | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) 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'); + }); });