Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 9e35b50

Browse files
committed
fix(forEach): add the array/object as the 3rd param like the native array forEach
1 parent d7bfda6 commit 9e35b50

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/Angular.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ function isArrayLike(obj) {
208208
*
209209
* @description
210210
* Invokes the `iterator` function once for each item in `obj` collection, which can be either an
211-
* object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value`
212-
* is the value of an object property or an array element and `key` is the object property key or
213-
* array element index. Specifying a `context` for the function is optional.
211+
* object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
212+
* is the value of an object property or an array element, `key` is the object property key or
213+
* array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
214214
*
215215
* It is worth noting that `.forEach` does not iterate over inherited properties because it filters
216216
* using the `hasOwnProperty` method.
@@ -238,19 +238,19 @@ function forEach(obj, iterator, context) {
238238
// Need to check if hasOwnProperty exists,
239239
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
240240
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
241-
iterator.call(context, obj[key], key);
241+
iterator.call(context, obj[key], key, obj);
242242
}
243243
}
244244
} else if (obj.forEach && obj.forEach !== forEach) {
245245
obj.forEach(iterator, context);
246246
} else if (isArrayLike(obj)) {
247247
for (key = 0, length = obj.length; key < length; key++) {
248-
iterator.call(context, obj[key], key);
248+
iterator.call(context, obj[key], key, obj);
249249
}
250250
} else {
251251
for (key in obj) {
252252
if (obj.hasOwnProperty(key)) {
253-
iterator.call(context, obj[key], key);
253+
iterator.call(context, obj[key], key, obj);
254254
}
255255
}
256256
}

test/AngularSpec.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,51 @@ describe('angular', function() {
617617
forEach(obj, function(value, key) { log.push(key + ':' + value); });
618618
expect(log).toEqual(['length:2', 'foo:bar']);
619619
});
620+
621+
function testForEachSpec(expectedSize, collection) {
622+
var that = {};
623+
624+
forEach(collection, function(value, key, collectionArg) {
625+
expect(collectionArg).toBe(collection);
626+
expect(collectionArg[key]).toBe(value);
627+
628+
expect(this).toBe(that);
629+
630+
expectedSize--;
631+
}, that);
632+
633+
expect(expectedSize).toBe(0);
634+
}
635+
it('should follow spec with array', function() {
636+
testForEachSpec(2, [1,2]);
637+
});
638+
it('should follow spec with arguments', function() {
639+
testForEachSpec(2, (function(){ return arguments; }(1,2)));
640+
});
641+
it('should follow spec with string', function() {
642+
testForEachSpec(2, '12');
643+
});
644+
it('should follow spec with jQuery/jqLite', function() {
645+
testForEachSpec(2, jqLite("<span>a</span><span>b</span>"));
646+
});
647+
it('should follow spec with childNodes NodeList', function() {
648+
testForEachSpec(2, jqLite("<p><span>a</span><span>b</span></p>")[0].childNodes);
649+
});
650+
it('should follow spec with getElementsByTagName HTMLCollection', function() {
651+
testForEachSpec(2, jqLite("<p><span>a</span><span>b</span></p>")[0].getElementsByTagName("*"));
652+
});
653+
it('should follow spec with querySelectorAll HTMLCollection', function() {
654+
testForEachSpec(2, jqLite("<p><span>a</span><span>b</span></p>")[0].querySelectorAll("*"));
655+
});
656+
it('should follow spec with JSON', function() {
657+
testForEachSpec(2, {a: 1, b: 2});
658+
});
659+
it('should follow spec with function', function() {
660+
function f(){}
661+
f.a = 1;
662+
f.b = 2;
663+
testForEachSpec(2, f);
664+
});
620665
});
621666

622667

0 commit comments

Comments
 (0)