84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
function largestOfFour(arr) { return arr.map(Function.apply.bind(Math.max, null)); } largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
这Function.apply.bind(Math.max, null) 该怎么理解??
走同样的路,发现不同的人生
假如直接这样
function largestOfFour(arr) { return arr.map(Math.max); }
输出一定是四个NAN因为Math.max的参数不能是数组,一定是Math.max(1,2,3)这样的格式所以传给map的callback一定是可以处理数组的每一项由[1,2,3]变成1,2,3来看函数:
function largestOfFour(arr) { return arr.map(Function.apply.bind(Math.max, null)); }
单独拿出来看
Function.apply.bind(Math.max, null)
Function.apply里面的this被替换成Math.max,同时参数传过去null
这时候arr里面的每一项数组作为参数传递给Function.apply,由Math.max处理,而数组当做apply的第二个参数正好处理
不知道我解释的清不清晰~~
function largestOfFour(arr) { return arr.map(func); }
largestOfFour(这个Four其实是多余的,因为并不一定得是4个元素,1-n个元素都行)这个函数目的在于求一个二维数组中每个一维数组中的最大值。
largestOfFour
那么我们正常思路是什么呢,首先,肯定会用到map,这样我们只需要编写一个函数,这个函数接受一个数组,并返回一个数组中的最大值。但是已经有现成的max函数了,他虽然能返回最大值,但是接收的并不是一个数组,而是一连串的数字。这不符合我们的应用场景,但是程序猿是懒惰的,于是我们想,能不能稍微改造下这个max函数,利用他产生一个函数,这个函数接收的参数变成一个数组,而不是一连串数字。自然,我们就想到了apply,因为他可以将一个数组作为arguments传给一个函数。简单的小测试如下:
function func(v1, v2, v3) { console.log(v1 + ',' + v2 + ',' + v3); } func.apply(null, [1,2,3]); // 输出1,2,3
所以我们可以写出这样
return arr.map(function(ele) {return Math.max.apply(null, ele);});
但是这样我们创建了一个匿名函数,我们还想简化怎么办(虽然我比较喜欢这种写法,看起来简单很多。。)
好,现在确定下我们的目标,我们想得到一个函数。这个函数要完全基于Math.max,也就是函数体要相同(但我们不想要一个匿名函数去包裹他),这个时候我们就只能调用Function这个所有函数的父类了,通过他来创建函数。
但是我们不能直接Function.apply(Math.max)这样就已经调用了max了,我们现在需要的是一个函数的引用,而不是调用他。于是我们想到了bind,他能返回一个函数的副本,并且能改变this指向。
Function.apply(Math.max)
Function.apply.bind(Math.max, undefined, [2, 3, 4, 5, 6])()// orFunction.apply.bind(Math.max, undefined)([2, 3, 4, 5, 6])
即构建一个与Math.max函数体内容相同的函数,这里的undefined为Math.max里的this指向(bind的第一个参数为调用apply时的this指向,这里为Math.max,即构建一个与Math.max函数体内容相同的函数。第二个参数为追加在arguments之前的参数,如
function aa(){console.log(arguments);} aa.bind(null, 22)(33); // 输出22, 33
具体可以看看bind的用法这里)。
[2, 3, 4, 5, 6]为调用Math.max时的arguments指向。
上例中的[2, 3, 4, 5, 6]是调用map函数时参数列表中的第一个参数(第一个参数为数组中的每个值,在第一次调用的时候即是题目中的[4, 5, 1, 3])
这样,就实现了我们想要的功能,即改造Math.max,利用他实现一个函数,这个函数接收一个数组作为参数,返回数组中的最大值。
这么理解:
function largestOfFour(arr) { return arr.map(function(val) { return Math.max.apply(null, val); }); }
确实有点绕儿
https://segmentfault.com/q/10...看这里。
假如直接这样
输出一定是四个NAN
因为Math.max的参数不能是数组,一定是Math.max(1,2,3)这样的格式
所以传给map的callback一定是可以处理数组的每一项由[1,2,3]变成1,2,3
来看函数:
单独拿出来看
Function.apply里面的this被替换成Math.max,同时参数传过去null
这时候arr里面的每一项数组作为参数传递给Function.apply,由Math.max处理,而数组当做apply的第二个参数正好处理
不知道我解释的清不清晰~~
largestOfFour
(这个Four其实是多余的,因为并不一定得是4个元素,1-n个元素都行)这个函数目的在于求一个二维数组中每个一维数组中的最大值。那么我们正常思路是什么呢,首先,肯定会用到map,这样我们只需要编写一个函数,这个函数接受一个数组,并返回一个数组中的最大值。但是已经有现成的max函数了,他虽然能返回最大值,但是接收的并不是一个数组,而是一连串的数字。这不符合我们的应用场景,但是程序猿是懒惰的,于是我们想,能不能稍微改造下这个max函数,利用他产生一个函数,这个函数接收的参数变成一个数组,而不是一连串数字。
自然,我们就想到了apply,因为他可以将一个数组作为arguments传给一个函数。简单的小测试如下:
所以我们可以写出这样
但是这样我们创建了一个匿名函数,我们还想简化怎么办(虽然我比较喜欢这种写法,看起来简单很多。。)
好,现在确定下我们的目标,我们想得到一个函数。这个函数要完全基于Math.max,也就是函数体要相同(但我们不想要一个匿名函数去包裹他),这个时候我们就只能调用Function这个所有函数的父类了,通过他来创建函数。
但是我们不能直接
Function.apply(Math.max)
这样就已经调用了max了,我们现在需要的是一个函数的引用,而不是调用他。于是我们想到了bind,他能返回一个函数的副本,并且能改变this指向。Function.apply.bind(Math.max, undefined, [2, 3, 4, 5, 6])()
// or
Function.apply.bind(Math.max, undefined)([2, 3, 4, 5, 6])
即构建一个与Math.max函数体内容相同的函数,这里的undefined为Math.max里的this指向(bind的第一个参数为调用apply时的this指向,这里为Math.max,即构建一个与Math.max函数体内容相同的函数。第二个参数为追加在arguments之前的参数,如
具体可以看看bind的用法这里)。
[2, 3, 4, 5, 6]为调用Math.max时的arguments指向。
上例中的[2, 3, 4, 5, 6]是调用map函数时参数列表中的第一个参数(第一个参数为数组中的每个值,在第一次调用的时候即是题目中的[4, 5, 1, 3])
这样,就实现了我们想要的功能,即改造Math.max,利用他实现一个函数,这个函数接收一个数组作为参数,返回数组中的最大值。
这么理解:
https://segmentfault.com/q/10...
看这里。