Wie funktioniert Math.max.apply ()?

82

Wie funktioniert das 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

Der obige Code findet die maximale Anzahl in der Liste. Kann mir jemand sagen, wie der folgende Code funktioniert? Es scheint, dass es funktioniert, wenn ich bestanden habenull or Math.

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

user-defined/Native functionsHaben alle Call- und Apply-Methoden, die wir verwenden können?

Shane
quelle

Antworten:

135

applyAkzeptiert ein Array und wendet das Array als Parameter auf die eigentliche Funktion an. Damit,

Math.max.apply(Math, list);

kann verstanden werden als,

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

Dies applyist eine bequeme Möglichkeit, ein Array von Daten als Parameter an eine Funktion zu übergeben. Merken

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

funktioniert nicht, da maxein Array nicht als Eingabe akzeptiert wird.

Es gibt noch einen weiteren Vorteil: applySie können Ihren eigenen Kontext auswählen. Der erste Parameter, an den Sie applyeine Funktion übergeben, befindet sich thisinnerhalb dieser Funktion. Hängt maxaber nicht vom aktuellen Kontext ab. Also würde alles anstelle von funktionieren 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

Da applytatsächlich in definiert istFunction.prototype , hat jedes gültige JavaScript-Funktionsobjekt applystandardmäßig eine Funktion.

thefourtheye
quelle
3
@Shane, weil es auch dann funktioniert, wenn wir den Kontext auf undefinedoder setzen null:) Wenn maxversucht wurde, auf etwas im Kontext zuzugreifen oder es zu ändern, wäre es fehlgeschlagen, wenn der Kontext auf undefinedoder gesetzt wäre null.
thefourtheye
2
@NiCkNewman Verwendet eigentlich Math.maxnicht den ersten Parameter, da er keinen Kontext benötigt. Es verarbeitet nur die Daten, die es in den Argumenten empfängt.
thefourtheye
1
@NiCkNewman Es ist zu breit, um es im Kommentarbereich zu diskutieren. Aber dieser Artikel thiswäre ein guter Ausgangspunkt. Es hat auch einen Abschnitt callundapply welche Details dies.
thefourtheye
2
Beste Erklärung für .apply () aller Zeiten!
Microcipcip
1
Warum null oder Mathe?
17

Kann mir jemand sagen, wie der folgende Code funktioniert?

Math.max.apply(Math,list)

Ruft eine Math.maxFunktion mit MathObjekt auf, die als thisReferenz in der Funktionsimplementierung (body) verwendet und listals Argumente übergeben werden soll.

Das entspricht also letztendlich

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

Es scheint, dass es funktioniert, wenn ich null oder Mathe übergebe.

Offensichtlich verwendet die Math.maxImplementierung keine Instanzvariable - es gibt keinen Grund dafür. Die native Implementierung würde nur durchlaufen argumentsund die maximale finden.

Verfügen alle benutzerdefinierten / nativen Funktionen über eine Call- und Apply-Methode, die wir verwenden können?

Ja, jede einzelne Funktion kann mit calloder aufgerufen werdenapply

Verweise:

zerkms
quelle
3

Ich werde zunächst sagen Math.max(...numbers)und Function.prototype.apply()sollte nur für Arrays mit relativ wenigen Elementen verwendet werden. (...) und apply schlagen entweder fehl oder geben das falsche Ergebnis zurück, wenn das Array zu groß ist

Math.max.apply(null | undefined | Math, numbers)ist das gleiche wie Math.max(...numbers)so würde ich Math.max(...numbers)aus ästhetischen Gründen empfehlen .

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

Wenn Sie das maximale Element in einem sehr großen numerischen Array suchen müssen, verwenden Sie die Array.reduce()Methode.

Array.reduce() kann verwendet werden, um das maximale Element in einem numerischen Array zu finden, indem jeder Wert verglichen wird:

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)

Fazit:

Numerisches Array, das relativ klein ist: Verwenden Sie Math.max(...numbers) Numerisches Array, das sehr groß ist: Verwenden Sie die Array.reduce()Methode

Voxun
quelle
1
Die JavaScriptCore-Engine hat ein fest codiertes Argumentlimit von 65536. Wenn Sie also apply () verwenden, sollten Sie sicherstellen, dass Ihre Arraygröße immer kleiner ist.
Chaarmann
2

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

Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2...sind Parameter und müssen Numbers MDN Math.max sein

Sie können nicht arrayals Math.maxParameter übergeben. Um ein Array zu übergeben, müssen Sie verwenden apply.

Anwenden

Der erste Parameter von apply ist this, der zweite ist array. Mathematische Methoden entsprechen statischen Methoden in anderen Sprachen. Dies bedeutet, dass keine Objektinstanz erforderlich ist, array.prototype.slicesodass Sie thisin diesem Fall nicht übergeben müssen .

Beispiel

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)

Wenn Sie ein Array als Parameter übergeben möchten, müssen Sie es verwenden apply, andernfalls verwenden Sie call.

a pply = a rray
c all = c omma getrennt
Mehr über call & apply

rflw
quelle