Як працює Math.max.apply ()?


82

Як 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мають метод виклику та застосування, який ми можемо використовувати ?.

Відповіді:


139

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за замовчуванням матиме функцію.


3
@Shane, тому що це працює навіть тоді, коли ми встановлюємо для контексту значення undefinedабо null:) Якби maxспробувати отримати доступ / змінити що-небудь у контексті, це не вдалося б, коли для контексту встановлено значення undefinedабо null.
четверте око

2
@NiCkNewman Насправді, Math.maxне використовуватиме перший параметр, оскільки йому не потрібен будь-який контекст. Він оперує лише даними, які отримує в аргументах.
четверте око

1
@NiCkNewman Це занадто широке обговорення в розділі коментарів. Але ця стаття thisбула б гарною відправною точкою. Вона також має розділ , callіapply в якому детально це.
четверте око

2
Найкраще пояснення .apply () ніколи!
Microcipcip

1
Чому нуль або математика?


17

Хто-небудь може сказати мені, як працює код нижче?

Math.max.apply(Math,list)

Викликає Math.maxфункцію з Mathоб’єктом, яка буде використана як thisпосилання у реалізації функції (тіло) та listпередана як аргументи.

Тож це врешті дорівнює

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

Здається, це працює, якщо я здаю нуль або математику.

Очевидно, що Math.maxреалізація не використовує змінну екземпляра - немає жодних причин для цього. Власна реалізація просто повториться argumentsі знайде максимум.

Чи всі визначені користувачем / власні функції мають метод виклику та застосування, який ми можемо використовувати ?.

Так, кожну окрему функцію можна викликати за допомогою callабоapply

Список літератури:


3

Я почну з того , 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

Якщо вам потрібно знайти максимальний елемент у дуже великому числовому масиві: використовуйте Array.reduce()метод.

Array.reduce() можна використовувати для пошуку максимального елемента в числовому масиві, порівнюючи кожне значення:

const numbers = [5, 6, 2, 3, 7];
const getMax = (numbers) => numbers.reduce((a, b) => Math.max(a, b));

const getMin = (numbers) => numbers.reduce((a, b) => Math.min(a, b));
	
const max = getMax(numbers)
const min = getMin(numbers)

console.log('max:', max)
console.log('min:', min)

Висновок:

Числовий масив, який є відносно малим: використовуйте Math.max(...numbers) дуже великий числовий масив: використовуйте Array.reduce()метод


1
Механізм JavaScriptCore має жорстко закодовану кількість аргументів 65536, тому, використовуючи apply (), ви повинні переконатися, що розмір вашого масиву завжди буде меншим.
Chaarmann

2

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.

pply = rray з все = з ОММОЙ відокремленим Більше про виклик і застосувати

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.