Jak działa Math.max.apply ()?


82

Jak to Math.max.apply()działa?

<!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

Powyższy kod znajduje maksymalną liczbę na liście. Czy ktoś może mi powiedzieć, jak działa poniższy kod? Wygląda na to, że działa, jeśli zdamnull or Math.

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

Czy wszystkie user-defined/Native functionsmają metodę call and apply, której możemy użyć?

Odpowiedzi:


139

applyakceptuje tablicę i stosuje ją jako parametry do rzeczywistej funkcji. Więc,

Math.max.apply(Math, list);

można rozumieć jako

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

Tak, applyjest to wygodny sposób przekazać tablicę danych jako parametry do funkcji. Zapamiętaj

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

nie zadziała, ponieważ maxnie akceptuje tablicy jako danych wejściowych.

Jest jeszcze jedna zaleta: używanie apply, możesz wybrać własny kontekst. Pierwszy parametr, do którego przekazujesz applydowolną funkcję, będzie stanowił thiswnętrze tej funkcji. Ale maxnie zależy od aktualnego kontekstu. Tak więc wszystko działałoby zamiast 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

Ponieważ applyjest faktycznie zdefiniowana w programieFunction.prototype , każdy prawidłowy obiekt funkcji JavaScript będzie applydomyślnie miał funkcję.


3
@Shane, ponieważ działa nawet wtedy, gdy ustawimy kontekst na undefinedlub null:) Gdyby maxpróbować uzyskać dostęp / zmienić cokolwiek w kontekście, nie powiodło się, gdy kontekst jest ustawiony na undefinedlub null.
thefourtheye

2
@NiCkNewman Właściwie Math.maxnie użyje pierwszego parametru, ponieważ nie potrzebuje on żadnego kontekstu. Działa tylko na danych, które otrzymuje w argumentach.
thefourtheye

1
@NiCkNewman Jest zbyt obszerny, aby omawiać go w sekcji komentarzy. Ale ten artykuł thisbyłby dobrym punktem wyjścia. Ma również sekcję calliapply która to szczegółowo opisuje.
thefourtheye

2
Najlepsze wyjaśnienie .apply () w historii!
Microcipcip

1
Dlaczego null lub matematyka?


17

Czy ktoś może mi powiedzieć, jak działa poniższy kod?

Math.max.apply(Math,list)

Wywołuje Math.maxfunkcję z Mathobiektem, który ma być używany jako thisodniesienie w implementacji funkcji (treść) i listprzekazywany jako argumenty.

Więc to ostatecznie równa się

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

Wygląda na to, że działa, jeśli przekażę null lub Math.

Oczywiście Math.maximplementacja nie wykorzystuje zmiennej instancji - nie ma powodu, aby to robić. Natywna implementacja po prostu dokona iteracji argumentsi znajdzie maksymalną.

Czy wszystkie funkcje zdefiniowane przez użytkownika / natywne mają metodę call i apply, której możemy użyć?

Tak, każdą funkcję można wywołać za pomocą calllubapply

Bibliografia:


3

Zacznę od stwierdzenia Math.max(...numbers)i Function.prototype.apply()powinienem być używany tylko dla tablic ze stosunkowo niewielką liczbą elementów. (...) i Apply zakończy się niepowodzeniem lub zwróci nieprawidłowy wynik, jeśli tablica jest zbyt duża

Math.max.apply(null | undefined | Math, numbers)jest taki sam jak Math.max(...numbers)ten, który polecam Math.max(...numbers)ze względów estetycznych.

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

Jeśli potrzebujesz znaleźć maksymalny element w tablicy numerycznej, który jest bardzo duży: użyj Array.reduce()metody.

Array.reduce() można użyć do znalezienia maksymalnego elementu w tablicy liczbowej, porównując każdą wartość:

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)

Wniosek:

Tablica numeryczna, która jest stosunkowo mała: użyj Math.max(...numbers) tablicy liczbowej, która jest bardzo duża: użyj Array.reduce()metody


1
Silnik JavaScriptCore ma zakodowany na stałe limit argumentów równy 65536, więc podczas korzystania z metody apply () należy upewnić się, że rozmiar tablicy będzie zawsze mniejszy.
Chaarmann

2

Math.max (wart1, wart2, ...)

Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2...są parametrami i muszą być liczbami MDN Math.max

Nie możesz podać arrayjako Math.maxparametrów. Aby przekazać tablicę, musisz użyć apply.

Zastosować

Pierwszy parametr zastosuj to this, a drugi to array. Metody matematyczne są równoważne statycznym w innych językach, co oznacza, że ​​nie wymaga instancji obiektu w przeciwieństwie do array.prototype.slicetego, więc thisw tym przypadku nie trzeba ich przekazywać .

Przykład

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)

Jeśli chcesz przekazać tablicę jako parametr, którego musisz użyć apply, w przeciwnym razie użyj call.

a pply = a rray
c all = c omma Separated Więcej o dzwoń i aplikuj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.