Array filter returns strange results

杀马特。学长 韩版系。学妹 提交于 2019-12-22 12:43:14

问题


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 athisArg parameter is provided, it will be used as the this value for each invocation of callbackfn.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!