Underscore 源码学习(三)
这次主要说剩余参数。
在 ES5 中,如果想要函数接收任意数量的参数,必须使用特殊变量 arguments
,举个例子,我们要实现一个加法函数,要求第一个数乘2,然后与其他数相加。
在 ES6 中,我们可以使用 ...
操作符,例如:
使用 ES5 我们无法给函数定义参数,而只能通过 arguments
来获取参数,这样写明显带来了可读性的降低。而 ES6 我们就可以在函数声明里面写明参数,对于不定长的参数,则可以使用 ...
操作符。...
还有另一个常用的应用场景,比如下面例子:
如果细看输出的[1, 2, 3]会发现他是这样的:
我们再试试下面的
再看下[1, 2, 3]这行输出里面是什么:
从 instanceof
我们就知道了 arguments
并不是真正的数组。伪数组实质是一个对象。
要把一个伪数组转为数组,可以这样用
上面这种做法在很多地方都可以看到。除了上面这样做之外,我们还可以使用 ES6 的 Array.from
来处理,如下:
但在 ES6 中,我们使用 ...
运算符并不存在这个问题,比如上面第二个例子,args
是一个数组。
鉴于此,我们应该尽量使用 ES6 剩余参数写法和 Array.from
的写法,因为这样更容易理解,而且写起来更简洁。
另外,我们还可以使用 ...
操作符来复制数组,如下:
额,说多了,其实我是想说说 Underscore 中的 restArgs 这个东西…
看下:
这个的作用就类似与 ES6 中的 ...
操作符。这段代码作用是把 func
中 startIndex
开始的(如果没有指定则为被函数声明参数的最后一位开始)后面的参数全部变为一个数组传入 func
中。
这里有几个可圈可点的地方:
fun.length 和 arguments.length
函数也具有length
方法,得到的值是函数定义的参数的个数,但注意如果中间有一个含默认值的参数,则这个数和后面的参数都不会计算进去。例如:1234function test1(arg1, arg2, arg3 = 1, arg4) {};function test2(arg1, arg2, arg3) {};test1.length; // 2test2.length // 3而
arguments.length
则一直表示传入函数的参数个数。使用
+
转换为数字
你可能注意到了下面这句话有个+
运算符。1startIndex = startIndex == null ? func.length - 1 : +startIndex;其用途就是尝试把
startIndex
转为数字,我们举例看下就明白了。123456var a = '123', b = '123s', c = '0x321', d = '-0', e = '-Infinity'+a; // 123+b; // NaN+c; // 801+d; // -0+e; // -Infinity应该很清楚了,就不说明了。
然后关于这里的switch
其实就是一个优化而已,前面都提到过了,不提了。
我们看下 Underscore 运用到 restArgs 方法的地方:
这个方法的作用是在 obj
的每个元素上面执行 method
方法,例如:
由于 method
需要的参数个数是未知的,所以我们这里使用了 args
再用 restArgs
达到类似 ...
操作符的效果。
本来还想说说 Underscore 的几个方法的…但是好像已经写了挺多的了,还是下一次再介绍吧,后面的很多方法其实都不难理解,不过最好结合他的实际应用例子这样就更容易去理解些。