如果一个函数接受另一个函数作为参数,那么我们称该函数为高阶函数
部分javascript的高阶函数
forEach和Map
let arr = [1, 2, 3];
Array.prototype.myForEach = function (callback) {
let len = this.length;
// 做一个健壮性的判断
if (typeof callback !== 'function') {
throw new Error('must be function');
}
for (let i = 0; i < len; i ++) {
callback.call(this, this[i], i);
}
}
Array.prototype.myMap = function (callback) {
let len = this.length;
let arr = [];
// 做一个健壮性的判断
if (typeof callback !== 'function') {
throw new Error('must be function');
}
for (let i = 0; i < len; i ++) {
arr.push(callback.call(this, this[i], i));
}
return arr;
}
reduce
reduce 方法使用场景
// 1. 累加
arr.reduce((pre, cur, index, arr) => {
return pre + cur;
}, 10);
// 2. 改写对象数组
let routes = [
{
path: "/",
components: "hello"
},
{
path: "/test",
components: "test"
}
];
routes.reduce((pre, cur) => {
pre[cur.path] = cur.components;
return pre;
}, {});
// 3. 对象数组部分属性相加
let arr = [
{
type: "all",
num: 1
},
{
type: "no",
num: 2
},
{
type: "all",
num: 3
},
];
arr.reduce((pre, curr) => {
if (curr.type === "all") {
pre += curr.num;
}
return pre;
}, 0);
手写reduce方法
// 手写reduce方法
Array.prototype.myReduce = function (fn, init) {
let i = 0;
let len = this.length;
let pre = init;
if (init === undefined) {
pre = this[0];
i = 1;
}
for (i; i < len; i ++) {
pre = fn.call(this, pre, this[i], i, this);
}
return pre;
}
filter
过滤
// 过滤返回为true的内容,以数组形式返回
let arr = [1, 2, 3, 4, 5, 6];
arr.filter((curr, index) => {
return curr % 2 === 0;
});
手写filter函数
Array.prototype.myFilter = function(fn) {
let _newArray = [];
let len = this.length;
for (let i = 0; i < len; i ++) {
if (fn.call(this, this[i], i)) {
// 如果值是对象,要解除与原对象的引用,克隆一个新的出来
// 不是就直接加进去
if (typeof this[i] === 'object') {
_newArray.push(Object.create(this[i]));
} else {
_newArray.push(this[i]);
}
}
}
return _newArray;
}
手写自己的高阶函数
编写高阶函数要注意的点
-
保持纯函数和减少函数副作用
-
调用选择call还是apply
当给回调函数的参数是指定数量的时候,选择call,不确定有多少个参数时选用apply,将arguments数组给它
编写自己的高阶函数
- 找出对象中符合要求的属性名
let obj = {
num1: 1,
num2: 2,
num3: 3,
num4: 4,
num5: 5,
num6: 6
};
// 筛选出对象中值能被二整除的属性名,接收两个参数,一个对象,一个对象的回调
function findProperty(obj, fn) {
let _obj = Object.create(obj);
let _propertyArr = [];
for (let item in _obj) {
// 这个方法的this指向window,看调用这个函数的方法,this指向哪里比较方便
// 筛选出执行结果为true的
if (fn.call(_obj, _obj[item], item)) {
_propertyArr.push(item);
}
}
return _propertyArr;
}
findProperty(obj, (value, name) => {
return value % 2 === 0;
});