Skip to content

Commit 39203ac

Browse files
committed
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 angular#8510 Closes angular#8522
1 parent fcd76d2 commit 39203ac

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

src/Angular.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ function forEach(obj, iterator, context) {
246246
}
247247
} else if (isArray(obj) || isArrayLike(obj)) {
248248
for (key = 0, length = obj.length; key < length; key++) {
249-
iterator.call(context, obj[key], key);
249+
if (key in obj) {
250+
iterator.call(context, obj[key], key);
251+
}
250252
}
251253
} else if (obj.forEach && obj.forEach !== forEach) {
252254
obj.forEach(iterator, context);

test/AngularSpec.js

+10
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,16 @@ describe('angular', function() {
650650
forEach(obj, function(value, key) { log.push(key + ':' + value); });
651651
expect(log).toEqual(['length:2', 'foo:bar']);
652652
});
653+
654+
655+
it('should not invoke the iterator for indexed properties which are not present in the collection', function() {
656+
var log = [];
657+
var collection = [];
658+
collection[5] = 'SPARSE';
659+
forEach(collection, function (item, index) { log.push(item + index); });
660+
expect(log.length).toBe(1);
661+
expect(log[0]).toBe('SPARSE5');
662+
});
653663
});
654664

655665

0 commit comments

Comments
 (0)