一、什么是高阶函数?
高阶函数: 如果一个函数接收另一个函数作为参数,那么我们称该函数为高阶函数。
二、JavaScript常见的高阶函数
forEach 和 map
// forEach 的源码
Array.prototype.myForEach = function (callback) {
var len = this.length;
if (typeof callback != 'function') {
throw new Error('must be function');
}
for (var i = 0; i < len; i++) {
callback.call(this, this[i], i);
}
}
// map 的源码
Array.prototype.myMap = function (callback) {
var len = this.length;
var arr = [];
if (typeof callback != 'function') {
throw new Error('must be function');
}
for (var i = 0; i < len; i++) {
arr.push(callback.call(this, this[i], i));
}
return arr;
}
reduce
// reduce 源码
Array.prototype.myReduce = function (fn, init) {
var i = 0;
var len = this.length;
var pre = init;
if (pre === undefined) {
pre = this[0];
i = 1;
}
for (i; i < len; i++) {
pre = fn.call(this, pre, this[i], i, this);
}
return pre;
}
filter
// filter 源码
Array.prototype.myFilter = function (fn) {
var len = this.length;
var arr = [];
for (var i = 0; i < len; i++) {
if (fn.call(this, this[i], i)) {
// 判断是否对象
if (typeof this[i] === 'object') {
arr.push(Object.create(this[i]));
} else {
arr.push(this[i]);
}
}
}
return arr;
}
三、自定义高阶函数
自定义高阶函数需要注意的点:
- 保持纯函数和减少函数副作用
- 调用选择 call 还是 apply(call:有明确的参数时;apply:参数个数不明确时)
自定义高阶函数的示例:
// 找出对象中符合要求的属性名
function filterName(obj, fn) {
var _obj = Object.create(obj);
var _nameArr = [];
for (var item in _obj) {
if (fn.call(_obj, _obj[item], item)) {
_nameArr.push(item);
}
}
return _nameArr;
}