携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第34天,点击查看活动详情
前言
本篇章我们将了解lodash里的rest方法使用和实现,在了解内部源码的过程中学习封装思想和重构手法。
rest方法主要是创建一个函数,调用参数func
时,this
绑定到创建的新函数,并且使用第二个参数start
之后的参数作为数组传入。
参数说明:
- 参数1:函数类型,表示应用rest参数的函数。
- 参数2:数字类型,表示rest参数的起始位置,默认值为[start=func.length-1]。
使用如下:
var say = _.rest(function(what, names) {
return what + ' ' + _.initial(names).join(', ') +
(_.size(names) > 1 ? ', & ' : '') + _.last(names);
});
say('hello', 'fred', 'barney', 'pebbles');
// => 'hello fred, barney, & pebbles'
实现上,对于非函数类型的参数直接抛出错误,内部会先对参数start
进行初始化赋值,会将其转换为整数,最后会返回baseRest的调用结果。
源码如下:
import baseRest from './_baseRest.js';
import toInteger from './toInteger.js';
var FUNC_ERROR_TEXT = 'Expected a function';
function rest(func, start) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
start = start === undefined ? start : toInteger(start);
return baseRest(func, start);
}
baseRest
baseRest是rest方法的基本实现,接收的参数和rest方法保持一致,内部会调用overRest和setToString方法,而identity方法则是返回传递的参数,方便后续方法迭代时调用。
import identity from './identity.js';
import overRest from './_overRest.js';
import setToString from './_setToString.js';
function baseRest(func, start) {
return setToString(overRest(func, start, identity), func + '');
}
overRest
overRest方法是baseRest方法的专用版本,用于转换rest数组。其中第一个参数和第二个参数跟rest方法以及baseRest方法一致,该方法有第三个参数,表示转换rest数组。
import apply from './_apply.js';
var nativeMax = Math.max;
function overRest(func, start, transform) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherArgs = Array(start + 1);
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = transform(array);
return apply(func, this, otherArgs);
};
}
apply
function apply(func, thisArg, args) {
switch (args.length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
setToString
setToString方法我们在《 lodash里的内部方法getFuncName和setToString 》中已经了解,这里就不多做赘述。
小结
本篇章我们通过了解rest方法的使用和源码实现,学习了其核心方法beseRest的实现,同时也了解到内部方法overRest和setToString 的实现,在学习源码的过程中理解lodash封装思想和函数提炼等手法。