Подтвердить что ты не робот

Почему не работает [ "A", "B", "C" ]. Map (String.prototype.toLowerCase.call)?

Это, конечно, возвращает то, что вы ожидаете:

["A","B","C"].map(function (x) {
    return x.toLowerCase();
});
// --> ["a", "b", "c"]

Так же использует String.prototype.toLowerCase.call:

["A","B","C"].map(function (x) {
    return String.prototype.toLowerCase.call(x);
});
// --> ["a", "b", "c"]

Он также работает, если вы передаете дополнительные аргументы, заданные картой, поскольку это отбрасывает аргументы:

["A","B","C"].map(function (x, index, arr) {
    return String.prototype.toLowerCase.call(x, index, arr);
});
// --> ["a", "b", "c"]

Но это не работает:

["A","B","C"].map(String.prototype.toLowerCase.call);
// --> TypeError: undefined is not a function

Не работает также следующее, поскольку arguments имеет прототип объекта вместо прототипа Array, поэтому slice есть undefined. Является ли причина вышеуказанного поведения, возможно, из-за чего-то вроде этого: где slice или какая-либо другая аналогичная функция Array используется внутри?

["A","B","C"].map(function (x) {
    return String.prototype.toLowerCase.apply(x, arguments.slice(1));
});
// --> TypeError: undefined is not a function
4b9b3361

Ответ 1

Это особое поведение точечной нотации JavaScript.

toLowerCase.call(x) работает, потому что JavaScript использует toLowerCase как this при выполнении call. Вот как call (который является тем же самым Function.prototype.call, который вы найдете на каждой функции) знает, что вы хотите выполнить toLowerCase.

Передача call в другую функцию теряет эту ссылку, поэтому this больше не относится к toLowerCase.

Ответ 3

Проблема заключается в том, что String.prototype.toLowerCase.call == Function.prototype.call. Если вы хотите получить функцию, которая преобразует аргумент в нижний регистр, вы можете привязать функцию toLowerCase к функции call следующим образом:

var toLowerCase = String.prototype.toLowerCase.call.bind(String.prototype.toLowerCase);
["A","B","C"].map(toLowerCase);

Ответ 4

Но это не работает:

[ "А", "В", "С" ] карта (String.prototype.toLowerCase.call);.

Первым аргументом, переданным map, должна быть функция, которая будет передана значение элементов массива. Вышеприведенная информация ссылается на функцию Function.prototype.call, поэтому функция будет пытаться:

call(x);

Таким образом, вызов был передан без его установки, поэтому при входе в функцию вызова будет undefined.