JS 中通过apply实现数组中,查找最大值的方法原理是什么?

JS数组中无法直接通过Math.max查找数组中元素的最大值,但可以通过apply方法实现,底层实现逻辑及原理是什么样的呢?

Math.max.apply(null, [1,2,3]);
阅读 2.8k
5 个回答

我们这样来理解,
首先,

Math.max(value0, value1, /* … ,*/ valueN) 

这个函数的参数并不是数组,比如你有N个数字比大小,哪它就要输入N个参数,
对于在数组中的数字,你把整个数组当参数给它,Math.max就认为只有一个参数了。所以比不了

也就是说,你要把数组中每一位数字,都转成它的参数

const arr=[1,2,3]
//最笨的办法是
Math.max(arr[0],arr[1],arr[2])
//最新的办法
Math.max(...arr)

上面都是把数组的每一位,变成参数传个Math.max

哪为什么,Function.prototype.apply() 就可以呢,因为apply(thisArg, argsArray),第二个参数,就是接受一个数组对像,把它变成调用者的所有参数,

Math.max 原来的用法是 Math.max(1,2,3),是不支持

Math.max([1,2,3]) // 不支持这种用法

再看一下apply的定义,第一个参数是this的指向,这里用不到,直接null;第二个参数是一个参数的单数组。这时候把[1,2,3]数组当做第二个参数传入,就实现了

Math.max(1,2,3)

因为数组没有Math.max方法, 所以需要借用Math方法, apply方法能劫持另外一个对象的方法,继承另外一个对象的属性 ,入参需要传数组, 但是这里不需要改变Math的this就传入了null, 只使用了方法

文档。对一个函数调用 apply 的时候,可以将数组作为参数列表给给这个函数。第一个参数是 this 对象,给 null 表示没有 this

Math.max.apply(null, [1,2,3]) 可以认为等价于 Math.max(1, 2, 3)(把数组作为参数列表)。这里“认为”而不是直接等价,是因为 Math.max 实际有 this,即 Math 作为一个对象时的引用,而 apply(null, ...) 直接把 this 替换成空了。

另外,ES6 以后(现在浏览器都支持),不需要这么麻烦,直接用展开运算 Math.max(...[1, 2, 3]) 就可以了。

  1. 首先 Math.max 函数接收的参数形式不是一个 JS 数组,而是接收多个参数(即数组的展开形式),所以 Math.max 不能直接传递数组。
  2. 其次 applyFunction 原型上的方法,函数都能调用 apply。 但需要注意的是: apply 第一个参数对象是 新this。第二个参数类型是数组,但数组中每一项会 单独的 作为参数,提供给目标函数使用(applyjs 内部实现只能模拟)。其实就相当于展开了数组的每一项。
  3. ES5+ 中,弥补了很多使用 ES5 之前使用不方便的特性, 实现了 展开运算符 (...),数组可以轻松的被展开。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏