数组过滤器返回奇怪的结果

时间:2016-03-26 08:20:51

标签: javascript arrays filter hasownproperty

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]

有谁知道为什么过滤器返回这些值? Spec of filterMDN doc也不清楚如何使用过滤器的第二个参数。

2 个答案:

答案 0 :(得分:7)

Array.prototype.filter的第二个参数是将this设置为作为第一个参数传递的函数的值。

所以你的代码最终会像:

arr.filter(function(v, i, a) {
    return Object.hasOwnProperty.call("222", v, i, a);
});

因此它基本上检查"222"字符串是否具有您在数组中枚举的属性。

由此可以清楚地了解为什么找到属性012 - 因为这些是"222"字符串中字符的索引,并且说, ,9{"abc":123}不是 - 因为"222"字符串没有这样的属性。

与长字符串相同的故事,其中还包括属性46,因为它更长。

一些例子:

Object.hasOwnProperty.call("222", 1); // true, because `"222"[1]` is there
Object.hasOwnProperty.call("222", 'foo'); // false, because `"222"['foo']` is not there

答案 1 :(得分:3)

从规范中可以清楚地看出来。

  

Array.prototype.filter ( callbackfn [ , thisArg ] )

     

如果提供了thisArg参数,则会将其用作this值   每次调用callbackfn

所以:

var arr = [0,1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]];
arr.filter(Object.hasOwnProperty,"2222222");

按顺序转换为这些调用

"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]

它所说的行true是因为字符串可以索引到相似的数组中,所以带有两个字符的字符串将索引01作为自己的属性。