2016-03-26 3 views
2

относящиеся к 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 filter и MDN doc также не ясно показывают, как используется второй аргумент фильтра.

+2

@ дорогие-downvoters, пожалуйста, дайте мне знать, как я могу улучшить этот вопрос. – gurvinder372

+2

В спецификации указано 'Array.prototype.filter (callbackfn [, thisArg])' right в заголовке и *. Если предоставлен параметр 'thisArg', он будет использоваться как это значение для каждого вызова' callbackfn'. "* в пункте позже - Как это может быть более ясно, чем это? – Tomalak

+0

@ Томалак хорошо мне было непонятно, простите мое невежество. Иначе зачем задавать вопрос? Говорить, что 'оно будет использоваться как это значение для каждого вызова', не является exaccty' 2 + 2 = 4'. – gurvinder372

ответ

7

Второй аргумент 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 
+0

классный, очень хорошо объяснил. Спасибо – gurvinder372

+0

Чтобы быть педантичным, это не '' 222 "[1]' но 'new String (" 222 ") [1]' - autoboxing. – georg

+1

@georg '" 222 "[1]' - выражение, которое включает авто бокс под капотом, поэтому я не вижу смысла. – zerkms

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 являются потому, что строки могут быть проиндексированы в как массивы, так что строка с двумя символы имеют индексы 0 и 1 как собственные.

+0

Спасибо, ваши столы еще более понятны. – gurvinder372

+0

Как мы реорганизуем или иным образом убеждаем '{" abc ": 123} .hasOwnProperty (" abc ");'? Хотя в правильной форме для возврата '{" abc ": 123}' из '.filter()'? – guest271314

+0

@ guest271314 Вы имеете в виду '({" abc ": 123}). HasOwnProperty (" abc ")'? – gurvinder372

Смежные вопросы