84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
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...
看这里。