Question 22 / 31
How does filter's second argument change this inside the callback?
Topic: this bindingDifficulty: Intermediate
Several array iteration methods accept an optional thisArg that overrides the callback's this.
Solve it with the execution visualizerStep through every binding, function call, and console output below.Predict the output
Predict all three lines. The callback is a plain function — how does it end up reading obj.a?
var obj = { a: 'obj' };
var a = 'window';
var arr = [1, 2, 3];
arr.filter(function (item) {
console.log(item, this.a);
return item > 2;
}, obj);Reveal the answer and explanation
Expected output
1 obj
2 obj
3 objWhy this happens
Array.prototype.filter accepts an optional second argument, thisArg. When present, the specification calls the callback using that value as this instead of the default binding a bare invocation would otherwise produce.
Here obj is passed as thisArg, so for every element, this inside the callback is explicitly set to obj, and this.a reads "obj" each time.
filter still calls the callback once per array element (1, 2, then 3), each time pairing the element with this.a, giving three lines of "obj".
What this question tests
- forEach, map, filter, some, and every all accept an optional thisArg
- thisArg overrides what would otherwise be default binding inside the callback
- this override happens per-call, arranged internally by the array method, not by the call syntax written in the source
Runtime assumptions
The thisArg parameter is part of the specified behavior of these array methods in every standard JavaScript environment.