JavaScript高阶函数

 

高阶函数是指满足以下两个条件中至少一个的函数:

(1)函数作为参数传入

(2)函数作为返回值返回

 

下面,详细介绍两种情况。

首先,函数作为参数传入,最典型的是 回调函数

ajax('http://www.baidu.com', function(err, data) {
    console.log(data);
})

比如上面的情景,回调函数作为参数传入,用于处理异步的一些场景

 

然后再看一下另一种情景,

arr.sort(function(a, b) {
    return a - b;
});

函数传入作为参数,用于排序

 

然后是函数作为返回值的情况,比如单例模式:

var single = (function(fn) {
    var ret;
    return function() {
        return ret || (ret = fn.apply(this, arguments));
    };
});

像这样,可以通过返回函数的形式实现一个单例模式

 

接下来,介绍一些具体的 高阶函数:

 

1. AOP(面向切面编程)

AOP的意义在于,将与中心业务逻辑无关的部分抽离出来,比如日志统计、错误处理、安全控制等等。这样可以保持业务逻辑模块的低内聚。

 

Function.prototype.before = function(before) {
    var _this = this;
    return function() {
        before.apply(this, arguments);
        return _this.apply(this, arguments);
    };
};

Function.prototype.after = function (after) {
    var _this = this;
    return function() {
        var ret = _this.apply(this, arguments);
        after.apply(this, arguments);
        return ret;
    };
};

var fn = function() {
    console.log(2);
};

fn.before(function() {
    console.log(1);
}).after(function() {
    console.log(3)
});

fn();

 

这种形式就可以实现对函数进行运行前后的一些控制,也叫做装饰者模式。

 

2. 柯里化

函数柯里化实际上是指,将部分参数传入函数进行调用,返回一个函数来处理剩下的参数。

如:

 

function add(a) {
    return function(b) {
        return a + b;
    }
}

 

如上面这个函数:

 

var a = add(1)(2);
//a === 3 

将多参数分解成单参数

函数柯里化更多用在函数式编程里面,具体可以参照我的《对JavaScript函数式编程的一点理解》

 

3. uncurrying

uncurrying主要是用于将泛化this提取出来

Function.prototype.uncurrying = function() {
    var self = this;
    return function() {
        var obj = Array.prototype.shift.call(arguments);
        return self.apply(obj, arguments);
    }
}

这样之后,我们来改装一下push函数

var push = Array.prototype.push.uncurrying();
(function() {
    push(arguments, 4);    //1, 2, 3, 4
})(1, 2, 3);

这样就实现我们的目标了

 

4. 函数节流

有些函数运行的频率可能极高,比如:

(1)window.onresize

(2)onmousemove

这些都可能导致函数频繁调用,这时候我们可以用节流函数

var throttle = function (fn, time) {
	var _self = fn,
		timer,
		firstTime;

	return function() {
		var args = arguments,
			_this = this;
		if (firstTime) {
			_self.apply(_this, args);
			return firstTime = false; 
		}

		if (timer) {
			return false;
		}

		timer = setTimeout(function() {
			clearTimeout(timer);
			timer = null;
			_self.apply(_this, args);
		}, time);
	}
}

window.onresize = throttle(function() {
	console.log(1);
}, 1000);

通过这种写法,我们可以让函数间隔一段时间再调用,而不会立刻调用

 

5. 分时函数

有时候要将数据放到DOM中,可能有几千甚至几万个数据,这时不能一次性将它放进DOM,不然会导致卡顿。

这时我们要用分时函数。代码如下:

var timeChunk = function(arr, fn, count) {
	var timer;

	var start = function() {
		for (var i = 0; i < Math.min(arr.length, count || 1); i++) {
			var obj = arr.shift();
			fn(obj);
		}
	};

	return function() {
		timer = setInterval(function() {
			if (arr.length === 0) {
				return clearInterval(timer);
			}
			start();
		}, 200);
	};
};

 

这样就可以实现分时调用函数了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值