群主分享了这么一段代码,应邀分析一下,以下是正文。
new Array(101).join(' ').replace(/ /g,function(t,i){
return i+1+' '
}).split(' ').reduce(function(n1,n2) {
return (n1-0)+(n2-0)
});
首先 new Array(101).join(' ')
会创建 100 个 " "
空格字符。为什么是 100 个空格?
new Array(101)
创建了 101 个 undefined
。再调用 join(' ')
用空格把这 101 个 undefined
分割位 100 个 " "
(空格字符)组成的字符。
空说无凭,来看代码:
var arr = new Array(101); // 101 个 undefined
arr.toString(); // -> ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
arr.join(' '); // 用空格替换上面的 100 个 , (逗号)
然后调用 replace()
方法将每个空格替换成数字。
这里 / /g
全局替换就不解释了,注意 repalce()
中的 replacement 是一个函数:
function(t, i) {
return i + 1 + ' ';
}
这个函数种的参数 t
就是对应的每个数组项的值 - " "
;i
就是当前要替换的字符在原字符串中的索引,因为 JavaScript 数组项,字符串中的字符 - 这些东西的索引都是从 0 开始的,因此直接用 i
计算只能得到 0 - 99 的数字。而每个索引 + 1
(i + 1
) 就能得到 1-100 的数字。
然后,你会发现 repalcement 返回的结果里面有个 + ' '
,而这个 + ' '
会将 i + 1
得到的数字转为字符串,最后:
new Array(101).join(' ').replace(/ /g,function(t,i){return i+1+' '}); // 得到一个 "1 2 3 ... 100" 这样的字符串(用空格分割每个数字的字符串)。
注意这里为什么在 replacement 里面返回的结果种要加一个[空格]。继续看下面。
有了这么一个字符串之后,再用 split(' ')
把这个字符串转为数组:
上面加的空格就是为了这里再次用[空格]分割。
new Array(101).join(' ').replace(/ /g,function(t,i){return i+1+' '}).split(' '); // 这样就得到 [1,2,3,4...,100] 这样的字符串数组,注意这里数组的每一项是字符串
其实,最后就是根据这个数组求和。而这个求和的巧妙之处就是 reduce
(归并)的使用。
看一下归并的定义:
迭代数组所有的项目,构建一个最终返回的值。
这个 reduce()
方法可以传递一个在每一项(数组每一项)上面调用的函数,而这个函数有四个参数:
prev
前一个值cur
- 当前值index
- 当前项的索引array
- 原数组
语法:
arr.reduce(function(prev, cur, index, array) {
// do something
});
再看看上面那段代码种最后的:reduce(function(n1,n2){return (n1-0)+(n2-0)})
这里 n1
就是前一个值,第一次归并的时候它就是第一项,n2
就是当前值,第一次归并的时候它就是第二项。而索引和原数组用不到,这里就不放出来了。
回调函数种的 n1- 0
, n2-0
都是把字符串转成数字之后相加。前面提到过:new Array(101).join(' ').replace(/ /g,function(t,i){return i+1+' '}).split(' ');
返回的是字符串数组。
这个归并函数 - reduce
最终会迭代操作数组的每一项之后返回__一个结果__。而这里,刚好以累加的方式迭代这个数组实际上就是 1 - 100 的求和。
reduce()
方法是 ECMAScript 5 中新增的,不要问为什么我的 IE6 报错。