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/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/max

上面的代码在列表中找到最大数。谁能告诉我下面的代码如何工作?如果我通过的话似乎可行null or Math.

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

是否所有user-defined/Native functions我们都可以使用的调用和应用方法?

Answers:


136

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,因此apply默认情况下,任何有效的JavaScript函数对象都将具有函数。


3
@Shane因为,即使我们将上下文设置为undefined或,它也可以工作null:)如果max尝试访问/更改上下文中的任何内容,则当上下文设置为undefined或时它将失败null
thefourtheye 2014年

2
@NiCkNewman实际上,Math.max将不会使用第一个参数,因为它不需要任何上下文。它仅对在参数中接收的数据进行操作。
thefourtheye 2015年

1
@NiCkNewman太宽泛,无法在评论部分进行讨论。但是这篇文章this将是一个很好的起点。它也有一个部分call,并apply详述此。
thefourtheye

2
.apply()的最佳解释!
Microcipcip

1
为什么选择null或数学?


17

谁能告诉我下面的代码如何工作?

Math.max.apply(Math,list)

调用Math.max带有Math对象的函数,以将其用作this函数实现(主体)中的引用并list作为参数传递。

所以这最终等于

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

如果我通过null或Math,似乎可以使用。

显然Math.max实现不使用实例变量-没有理由这样做。本机实现只会迭代arguments并找到最大的实现。

所有用户定义/本机函数是否都具有我们可以使用的call和apply方法?

是的,可以使用call或来调用每个函数apply

参考文献:


3

我首先要说Math.max(...numbers)Function.prototype.apply()仅应用于元素相对较少的数组。如果数组太大,则(...)和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
Ç所有= Ç OMMA分离
更多关于呼叫&申请

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.