Related to this question, i wanted to try out this
var arr = [0,1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]];
arr.filter(Object.hasOwnProperty,"abc");//outputs [0, 1, 2]
arr.filter(Object.hasOwnProperty,"2222222") //[0, 1, 2, 4, 6]
Does anyone knows why filter return these values? Spec of filter and MDN doc also doesn't clearly tell how second argument of filter is used.
The second argument to the Array.prototype.filter
is the value that will be set as this
to the function that is passed as a first argument.
So your code ends up to be something like:
arr.filter(function(v, i, a) {
return Object.hasOwnProperty.call("222", v, i, a);
});
So it basically checks if the "222"
string has the properties you enumerate in the array.
From that it becomes clear why properties 0
, 1
and 2
are found - since those are the indexes of the characters in the "222"
string, and, say, 9
or {"abc":123}
are not - since "222"
string does not have such a properties.
It is the same story with the longer string, which also includes properties 4
and 6
just because it's longer.
Some examples:
Object.hasOwnProperty.call("222", 1); // true, because `"222"[1]` is there
Object.hasOwnProperty.call("222", 'foo'); // false, because `"222"['foo']` is not there
It's crystal clear from the spec
Array.prototype.filter ( callbackfn [ , thisArg ] )
,If a
thisArg
parameter is provided, it will be used as thethis
value for each invocation ofcallbackfn
.
So:
var arr = [0,1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]];
arr.filter(Object.hasOwnProperty,"2222222");
translates to these calls, in sequence
"2222222".hasOwnProperty(0); // true -> 0
"2222222".hasOwnProperty(1); // true -> 1
"2222222".hasOwnProperty(2); // true -> 2
"2222222".hasOwnProperty(true); // false ->
"2222222".hasOwnProperty(4); // true -> 4
"2222222".hasOwnProperty({"abc":123}); // false ->
"2222222".hasOwnProperty(6); // true -> 6
"2222222".hasOwnProperty(7); // false ->
"2222222".hasOwnProperty({"def":456}); // false ->
"2222222".hasOwnProperty(9); // false ->
"2222222".hasOwnProperty([10]); // false ->
// filter() => [0,1,2,4,6]
The lines where it says true
are because strings can be indexed into like arrays, so a string with two characters has the indexes 0
and 1
as own properties.
来源:https://stackoverflow.com/questions/36233124/array-filter-returns-strange-results