Skip to content

Instantly share code, notes, and snippets.

@basecss
Created February 23, 2016 08:26
Show Gist options
  • Save basecss/0c2204e7ee29b4b710d8 to your computer and use it in GitHub Desktop.
Save basecss/0c2204e7ee29b4b710d8 to your computer and use it in GitHub Desktop.

群主分享了这么一段代码,应邀分析一下,以下是正文。

代码

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 的数字。而每个索引 + 1i + 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 报错。

参考资料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment