¿Cómo funciona Math.max.apply ()?

82

¿Cómo Math.max.apply()funciona ?.

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

El código anterior encuentra el número máximo en la lista. ¿Alguien puede decirme cómo funciona el siguiente código? Parece que funciona si pasonull or Math.

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

¿Todos user-defined/Native functionstienen el método de llamada y aplicación que podemos usar?

Shane
fuente

Respuestas:

136

applyacepta una matriz y aplica la matriz como parámetros a la función real. Entonces,

Math.max.apply(Math, list);

puede entenderse como,

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

Por lo tanto, applyes una forma conveniente de pasar una matriz de datos como parámetros a una función. Recuerda

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

no funcionará porque maxno acepta una matriz como entrada.

Hay otra ventaja de usar apply, puedes elegir tu propio contexto. El primer parámetro al que pasa applyde cualquier función será el thisinterior de esa función. Pero maxno depende del contexto actual. Entonces, cualquier cosa funcionaría en lugar de 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

Dado applyque en realidad está definido enFunction.prototype , cualquier objeto de función de JavaScript válido tendrá applyfunción de forma predeterminada.

los cuatro ojos
fuente
3
@Shane porque, funciona incluso cuando configuramos el contexto en undefinedo null:) Si maxintentamos acceder / cambiar algo en el contexto, habría fallado cuando el contexto está configurado en undefinedo null.
thefourtheye
2
@NiCkNewman En realidad, Math.maxno usará el primer parámetro, ya que no necesita ningún contexto. Opera solo sobre los datos que recibe en los argumentos.
thefourtheye
1
@NiCkNewman Es demasiado amplio para discutirlo en la sección de comentarios. Pero este artículo thissería un buen punto de partida. También tiene una sección callyapply que detalla esto.
thefourtheye
2
¡La mejor explicación de .apply () jamás!
Microcipcip
1
¿Por qué nulo o matemático?
17

¿Alguien puede decirme cómo funciona el siguiente código?

Math.max.apply(Math,list)

Invoca una Math.maxfunción con Mathobjeto para utilizarla como thisreferencia en la implementación de la función (cuerpo) y listpasarla como argumentos.

Entonces esto eventualmente equivale a

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

Parece que funciona si paso null o Math.

Obviamente, la Math.maximplementación no usa la variable de instancia, no hay razón para hacerlo. La implementación nativa simplemente iteraría argumentsy encontraría la máxima.

¿Todas las funciones nativas / definidas por el usuario tienen un método de llamada y aplicación que podemos usar?

Sí, todas las funciones se pueden invocar usando calloapply

Referencias:

zerkms
fuente
3

Comenzaré diciendo Math.max(...numbers)y Function.prototype.apply()solo debería usarse para matrices con relativamente pocos elementos. (...) aplicar fallará o devolverá el resultado incorrecto si la matriz es demasiado grande

Math.max.apply(null | undefined | Math, numbers)es lo mismo que Math.max(...numbers)yo recomendaría Math.max(...numbers)por razones estéticas.

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

Si necesita encontrar el elemento máximo en una matriz numérica que es muy grande: use elArray.reduce() método.

Array.reduce() se puede utilizar para encontrar el elemento máximo en una matriz numérica, comparando cada valor:

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)

Conclusión:

Matriz numérica que es relativamente pequeña: use una Math.max(...numbers) matriz numérica que sea muy grande: use el Array.reduce()método

voxun
fuente
1
El motor JavaScriptCore tiene un límite de argumentos codificado de forma rígida de 65536, por lo que cuando use apply () debe asegurarse de que el tamaño de su matriz siempre sea menor.
Chaarmann
2

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

Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2...son parámetros y deben ser Numbers MDN Math.max

No puede pasar arraycomo Math.maxparámetros. Para pasar una matriz tienes que usar apply.

Aplicar

El primer parámetro de aplicar es this, el segundo es array. Los métodos matemáticos son equivalentes a estáticos en otros lenguajes, lo que significa que no necesita una instancia de objeto a diferencia de, array.prototype.slicepor lo que no necesita pasar thisen este caso.

Ejemplo

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)

Cuando desee pasar una matriz como parámetro, debe usar apply, de lo contrario, use call.

a pply = a rray
c all = c omma separados
Más sobre llamar y aplicar

rflw
fuente