携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
前言
在lodash中,after、before、once、negate方法被归类为函数类,主要是对函数类型的数据进行拓展。
after
after方法可以创建一个函数,当他被调用第一个参数n或更多次之后将马上触发第二个参数func 函数 。
使用如下:
var saves = ['profile', 'settings'];
var done = _.after(saves.length, function() {
console.log('done saving!');
});
done()
done()
// => done方法在两次调用之后,后续调用会一直输出'done saving!'
after方法的实现主要借助toInteger方法,将数据转化为整数类型,利用闭包特性,当值达到某个零界点时停止执行,绑定this用到了apply方法。
源码如下:
import toInteger from './toInteger.js';
var FUNC_ERROR_TEXT = 'Expected a function';
function after(n, func) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
n = toInteger(n);
return function() {
if (--n < 1) {
return func.apply(this, arguments);
}
};
}
before
before方法可以创建一个函数,该函数接收两个参数,其中第一个参数n 代表调用次数,第二个参数是供内部调用的函数func,通过this绑定和创建函数的参数调用func,调用次数不超过 n 次。 之后再调用这个函数,将返回一次最后调用func的结果。
使用如下:
fn = _.before(3, ()=>{console.log('run');return Math.random()})
fn()
// => 输出run,返回0.9970988584136162
fn()
// => 输出run,返回0.6064649946039051
fn()
// => 输出run,返回0.6064649946039051
fn()
// => 输出run,返回0.6064649946039051
同样的,before在实现上也借助了toInteger方法将数据转化为整数类型,利用闭包特性,对次数进行判断。
源码如下:
import toInteger from './toInteger.js';
var FUNC_ERROR_TEXT = 'Expected a function';
function before(n, func) {
var result;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
n = toInteger(n);
return function() {
if (--n > 0) {
result = func.apply(this, arguments);
}
if (n <= 1) {
func = undefined;
}
return result;
};
}
once
once方法表示创建一个只能调用 func (参数)一次的函数。 重复调用返回第一次调用的结果。 func 调用时, this 绑定到创建的函数,并传入对应参数。
使用如下:
var initialize = _.once(createApplication);
initialize();
initialize();
// => `initialize` 只能调用 `createApplication` 一次。
once方法实现上只需要调用before方法,对第一个参数传入2即可。
源码如下:
import before from './before.js';
function once(func) {
return before(2, func);
}
negate
negate方法可以创建一个针对断言函数 func 结果取反的函数。 func 断言函数被调用的时候,this 绑定到创建的函数,并传入对应参数。
使用如下:
var array = [1, 2, 3, 4, 5, 6]
array.filter(_.negate((item) => item % 2 === 0))
// => [1, 3, 5]
negate方法的实现借助!操作法取反操作,通过switch将参数限制在3个。
源码如下:
var FUNC_ERROR_TEXT = 'Expected a function';
function negate(predicate) {
if (typeof predicate != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
return function() {
var args = arguments;
switch (args.length) {
case 0: return !predicate.call(this);
case 1: return !predicate.call(this, args[0]);
case 2: return !predicate.call(this, args[0], args[1]);
case 3: return !predicate.call(this, args[0], args[1], args[2]);
}
return !predicate.apply(this, args);
};
}
小结
本篇章我们了解到了after、before、once、negate方法的使用以及代码实现,实现上基本上是借助闭包特性以及call或apply绑定this指向。