数组过滤器 returns 奇怪的结果
Array filter returns strange results
与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]
有谁知道为什么要过滤 return 这些值? Spec of filter and MDN doc 也没有清楚地说明 filter 的第二个参数是如何使用的。
Array.prototype.filter
的第二个参数是将被设置为 this
到作为第一个参数传递的函数的值。
所以你的代码最终是这样的:
arr.filter(function(v, i, a) {
return Object.hasOwnProperty.call("222", v, i, a);
});
所以它基本上检查 "222"
字符串是否具有您在数组中枚举的属性。
从这里可以清楚地看出为什么会找到属性 0
、1
和 2
- 因为这些是 "222"
字符串中字符的索引,并且,比如说,9
或 {"abc":123}
不是 - 因为 "222"
字符串没有这样的属性。
较长的字符串也是如此,它还包括属性 4
和 6
,只是因为它更长。
一些示例:
Object.hasOwnProperty.call("222", 1); // true, because `"222"[1]` is there
Object.hasOwnProperty.call("222", 'foo'); // false, because `"222"['foo']` is not there
crystal 规范
Array.prototype.filter ( callbackfn [ , thisArg ] )
,
If athisArg
parameter is provided, it will be used as the this
value
for each invocation of 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
的行是因为字符串可以被索引到类似的数组中,所以具有两个字符的字符串具有索引 0
和 1
作为自己的属性。
与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]
有谁知道为什么要过滤 return 这些值? Spec of filter and MDN doc 也没有清楚地说明 filter 的第二个参数是如何使用的。
Array.prototype.filter
的第二个参数是将被设置为 this
到作为第一个参数传递的函数的值。
所以你的代码最终是这样的:
arr.filter(function(v, i, a) {
return Object.hasOwnProperty.call("222", v, i, a);
});
所以它基本上检查 "222"
字符串是否具有您在数组中枚举的属性。
从这里可以清楚地看出为什么会找到属性 0
、1
和 2
- 因为这些是 "222"
字符串中字符的索引,并且,比如说,9
或 {"abc":123}
不是 - 因为 "222"
字符串没有这样的属性。
较长的字符串也是如此,它还包括属性 4
和 6
,只是因为它更长。
一些示例:
Object.hasOwnProperty.call("222", 1); // true, because `"222"[1]` is there
Object.hasOwnProperty.call("222", 'foo'); // false, because `"222"['foo']` is not there
crystal 规范
Array.prototype.filter ( callbackfn [ , thisArg ] )
,If a
thisArg
parameter is provided, it will be used as thethis
value for each invocation ofcallbackfn
.
所以:
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
的行是因为字符串可以被索引到类似的数组中,所以具有两个字符的字符串具有索引 0
和 1
作为自己的属性。