Как работает Math.max.apply()?

Как работает Math.max.apply()?

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
  <script>
      var list = ["12","23","100","34","56",
                                    "9","233"];
      console.log(Math.max.apply(Math,list));    
  </script>
</body>
</html>

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

Приведенный выше код находит максимальное количество в списке. Может ли кто-нибудь сказать мне, как работает код ниже?. Кажется, он работает, если я прохожу null or Math.

console.log(Math.max.apply(Math,list));

Есть ли у всех user-defined/Native functions метод вызова и применения, который мы можем использовать?

Ответ 1

apply принимает массив и применяет массив как параметры к фактической функции. Таким образом,

Math.max.apply(Math, list);

можно понимать как

Math.max("12", "23", "100", "34", "56", "9", "233");

Итак, apply - удобный способ передать массив данных в качестве параметров функции. Помните,

console.log(Math.max(list));   # NaN

не будет работать, потому что max не принимает массив в качестве входа.

Есть еще одно преимущество: использование apply, вы можете выбрать свой собственный контекст. Первый параметр, который вы передаете в apply любой функции, будет this внутри этой функции. Но max не зависит от текущего контекста. Итак, все будет работать на месте Math.

console.log(Math.max.apply(undefined, list));   # 233
console.log(Math.max.apply(null, list));        # 233
console.log(Math.max.apply(Math, list));        # 233

Так как apply фактически определен в Function.prototype, любой действительный объект функции JavaScript будет иметь функцию apply по умолчанию.

Ответ 2

На JavaScript ES6 просто используйте оператор Spread:

var list = ["12","23","100","34","56","9","233"];
console.log(Math.max(...list));
//                   ^^^ Spread operator 

Ответ 3

Может кто-нибудь сказать мне, как работает приведенный ниже код?

Math.max.apply(Math,list)

Вызывает функцию Math.max с объектом Math который будет использоваться как ссылка this в реализации функции (body) и list который будет передан в качестве аргументов.

Так что это в конечном итоге равно

Math.max("12","23","100","34","56", "9","233")

Кажется, это работает, если я передаю ноль или математику.

Очевидно, что реализация Math.max не использует переменную экземпляра - для этого нет причин. Нативная реализация просто перебирает arguments и находит максимальный.

Все ли пользовательские/родные функции имеют метод вызова и применения, который мы можем использовать?

Да, каждая функция может быть вызвана с помощью call или apply

Рекомендации:

Ответ 4

Math.max(val1, val2,...)

Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2... являются параметрами и должны быть Numbers MDN Math.max

Вы не можете передать array в качестве параметров Math.max. Чтобы передать массив, вы должны использовать apply.

Применить

Первый параметр apply - this, второй - array. Математические методы эквивалентны статическому в других языках, что означает, что ему не нужен экземпляр объекта в отличие от array.prototype.slice, поэтому вам не нужно передавать this в этом случае.

Пример

var arr = [1, 2, 3];

Math.max(1, 2, 3);  // -> 3
Math.max(arr);      // -> NaN (Not a Number)
Math.max.apply(null, arr);  // Math.max.apply(null, [1, 2, 3]) -> Math.max(1, 2, 3) -> 3

arr.slice(1);  // -> returns Array [2, 3]
Array.prototype.slice.call(arr, 1); // Array.prototype.slice.call([1, 2, 3], 1) == [1, 2, 3].slice(1)

Если вы хотите передать массив как параметр, вы должны использовать apply, в противном случае используйте call.

a pply = a rray
c все = c omma отделенные
Подробнее о вызове и применении

Ответ 5

Я начну с того, что Math.max(...numbers) и Function.prototype.apply() следует использовать только для массивов с относительно небольшим количеством элементов. (...) и применить будет либо сбой, либо вернет неправильный результат, если массив слишком большой

Math.max.apply(null | undefined | Math, numbers) совпадает с Math.max(...numbers) поэтому я бы порекомендовал Math.max(...numbers) по эстетическим соображениям.

const numbers = [5, 6, 2, 3, 7];

const max = Math.max(...numbers);

console.log('max:', max);
// expected output: 7

const min = Math.min(...numbers);

console.log('min:', min);
// expected output: 2