问题
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.
回答1:
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
回答2:
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