-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(forEach): match behaviour of Array.prototype.forEach (ignore missing properties) #8525
Conversation
So does this mean that in the following case, with this behavior in native code: var a = [];
var a[2] = 'hello';
a.forEach(function (value) {
console.log(value);
});
// output: 'hello'
// we don't get: undefined, undefined, 'hello' This was the behavior of When I apply the fix in this PR, the Angular Strap datepicker functions normally again. So +1! |
👍 Indeed |
…ing 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
@@ -245,8 +245,11 @@ function forEach(obj, iterator, context) { | |||
} | |||
} | |||
} else if (isArray(obj) || isArrayLike(obj)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the check for isArray()
is for performance reasons, since isArrayLike()
already returns true for arrays?
Okay, so the performance hit of testing if we have the profile has led to some discussion today, and which I've been thinking about internally:
From my POV, it wouldn't be that bad to use ES5 semantics in Obviously, the cost of testing if a property is available isn't free, but if we're honest, the cost isn't all that heavy (we're setill climbing through am array with a length of 10k and only 5k indexed properties over 1000 times per second on chrome desktop, and 600 times/second on mobile --- this isn't so bad). And since this is a regression, it's probably worth fixing regardless. We can have a fast compiler which doesn't care about sparse arrays while still supporting the expectations of angular users. This is doable --- but the decision needs to come from from someone else. Balls in your court~ |
Just out of interest, what is the benefit users get from using |
the benefit is, we did it before, and people used it, and then we stopped doing it and broke peoples code |
If I understand the method correctly, |
it would be good to add a jsperf link to this code and show that this is really faster than alternatives (hasOwnProperty, Object.keys()). otherwise it looks good to me. |
Here's a perf (it uses a very large array, in both sparse and full variants) http://jsperf.com/angular-foreach-comparison
|
http://jsperf.com/angular-foreach-comparison-small for smaller (~256) arrays, As far as the original semantics (and ECMAScript) semantics of the routine go, |
http://jsfiddle.net/caitp/Lrz5m5xs/ and this would be an example of why the Object.keys() case behaves very differently and is semantically incorrect. I can add each of these to the code in comments or something so that there's a note of it |
Yes. Please do.
|
So @IgorMinar's recent perf fixes have removed a lot of calls to |
@IgorMinar it would be good to cherry-pick this in stable since the regression technically exists there too, but the perf fixes which removed calls to |
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:
Closes #8510 Closes #8522