Предположим, у нас есть этот код
function largestOfFour(arr) {
return arr.map(Function.apply.bind(Math.max, null));
}
где arr - массив массивов.
Я понимаю, что при использовании метода Math.max() для работы с массивом я должен также добавить метод apply(). Так что у меня будет что-то вроде этого Math.max.apply(null, arr)
почему? что применяется apply()?
arr.map(Function.apply.bind(Math.max, null))
что на самом деле делает bind()?Пожалуйста, дайте объяснение, которое я могу понять, я действительно ценю это.
Глядя на все выражение:
arr.map(Function.apply.bind(Math.max, null));
map ожидает, что его первым аргументом будет функция, которая возвращается:
Function.apply.bind(Math.max, null);
Function.apply - это более короткая версия Function.prototype.apply.
Calling bind на нем возвращает специальную версию приложения, чье задание Math.max и когда вызывается, будет иметь в качестве первого параметра (т.е. Значение, которое обычно будет использоваться как это), равное null, поскольку оно не будет используемый.
Таким образом, каждый элемент в arr эффективно вызывается с использованием:
Math.max.apply(null, member);
Использование apply означает, что значения в члене передаются как параметры, как если бы:
Math.max(member[0],member[1] ... member[n]);
Таким образом, выражение возвращает максимальное значение в каждом массиве. Эти значения возвращаются на карту, что помещает их в новый массив.
var arr = [[1,2,3],[4,5,6]];
console.log(
arr.map(Function.apply.bind(Math.max, null)) //[3, 6]
);
и фактически это то же самое, что:
var arr = [[1, 2, 3],[4, 5, 6]];
console.log(
arr.map(function(a) {return Math.max.apply(null, a)}) //[3, 6]
);
Несмотря на использование последних функций, вы можете использовать деструкцию с синтаксисом параметра rest:
var arr = [[1, 2, 3],[4, 5, 6]];
console.log(
arr.map(a => Math.max(...a)) // [3, 6]
);
Функция Function.apply.bind(Math.max, null)
создает определение функции, когда invoked принимает значение null
в качестве первого параметра по умолчанию, и любые предоставленные параметры будут вторыми. Так как обратный вызов arr.map
эта функция (из-за оператора bind
) будет привязана к Math.max
но первый параметр Function.apply
будет иметь значение null
а второй - это элемент вспомогательного массива основного массива (из которого элементы должны быть переданы в качестве аргументов функции Math.max
).
Это старый трюк и в терминах arr.map(s => Math.max(...s));
будет делать ту же работу гораздо более четко.
Проще говоря, .apply
вызывает функцию с переданным ей набором аргументов (массив).
НАПРИМЕР:
const add = (...args) => args.reduce((acc, next) => acc + next);
Я могу вызвать функцию add
с любым количеством аргументов, используя метод .apply
подобный этому.
add.apply(null, [4, 2, 6, 76, 9]) // => 97.
Вы вызываете также использовать .call
но вместо передачи в аргументах, подобных массиву, вы просто передаете значения
add.call(null, 4, 2, 6, 76, 9) // => 97.
С .bind
разница заключается в том, что она создает новую функцию с вызовом, которая будет вызываться позже.
const addFunc = add.bind(null, 4, 2, 6, 76, 9);
addFunc() // -> 97.
Таким образом, поскольку это относится к функции, которую мы определили, она также применима к встроенным функциям, таким как Math.max
, Math.min
и т.д.
Надеюсь это поможет!