介绍
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value (mdn介绍)
这么一看似乎看起来很懵,我也是这样 然后就有了下面的学习记录
基本使用
[1, 2, 3, 4].reduce((pre, cur) => {
return pre + cur;
})
这是一个入门都会学的一个东西 数组求和 归纳函数每次归纳数组中的每一项(cur),然后将计算结果返回给累加器(pre), 然后反复迭代和归纳,将最后的结果(pre)返回回去,这样就到达了数组求和的目的。
多一个参数
[1, 2, 3, 4].reduce((pre, cur) => {
return pre + cur;
}, 5)
多加了一个参数之后初始的pre值会根据reduce的第二个参数初始化
画个图理解一下
pre被第二个参数初始化 然后cur不断移动 然后不断赋值给pre 直到遍历到最后 然后返回,如果没有传入初始化的的函数的话 pre会被初始化数组的第一个元素,然后cur指向下一个
理解不如手写
自己简写的
Array.prototype.myReduce = function (callback /*, initialValue */) {
var arr = this,
len = arr.length,
value = arguments[1] || arr[0];
var init = arguments[1] ? 0 : 1;
for (var i = init; i < len; i++) {
value = callback(value, arr[i], i, arr);
}
return value;
};
MDN的Polyfill
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, "reduce", {
value: function (callback, initialValue) {
if (this === null) {
throw new TypeError(
"Array.prototype.reduce called on null or undefined"
);
}
if (typeof callback !== "function") {
throw new TypeError(callback + "is not a function");
}
var o = Object(this);
var len = o.length >>> 0;
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
if (k >= len) {
throw new TypeError("reduce of empty array with no initial value");
}
value = o[k++];
}
while (k < len) {
if (k in o) {
value = callback(value, o[k], k, o);
}
k++;
}
return value;
},
});
}
MD的更加严谨 大家可以看我的理解一下 然后直接看官方的 这样能更好的理解
简单应用
扁平化数组
var arr = [1, 2, 3, 4, 5, ["zhangsna", "lisi", ["ss", "ss", ["ss", "ss"]]]];
function arrFlat(arr) {
return arr.reduce(function (pre, cur) {
// return pre.concat(Object.prototype.toString.call(cur) === '[object Array]'?arrFlat(cur):cur)
if (Object.prototype.toString.call(cur) === '[object Array]') {
return [...pre, ...arrFlat(cur)]
} else {
return [...pre, cur]
}
}, [])
}
console.log(arrFlat(arr))
组合函数
function toUpper(s) {
return s.toUpperCase();
}
function exclaim(str) {
return str + "!";
}
function exclaim1(str) {
return str + "?";
}
// compose组合函数
// reduce
function compose(...args) {
if (args.length === 0) return a => a;
if (args.length === 1) return args[0];
return args.reduce((pre, cur) => x => pre(cur(x)));
}
// reduceRight
function compose(...args) {
if (args.length === 0) return a => a;
if (args.length === 1) return args[0];
return x => args.reduceRight((res, cb) => cb(res), x);
}
// 大家体会一下用reduce和reduceRight的不一样的地方 两者实现函数的组合有一定的差别
reudx
大家用过React的话一定使用过redux吧 redux也是用reduce实现的,我给出我学习过程中的reudx的简单源码实现,大家可以看看更厉害的人写出来的源码分析 createStore.js
function createStore(reducer, enhancer) {
if (enhancer) {
return enhancer(createStore)(reducer);
}
let currentState = undefined;
let currentListeners = [];
function getState() {
return currentState;
}
function dispatch(action) {
currentState = reducer(currentState, action);
currentListeners.forEach((item) => {
item();
});
}
function subscribe(callback) {
currentListeners.push(callback);
}
dispatch({ type: '@INIT' });
return {
getState,
dispatch,
subscribe,
};
}
applyMiddleware.js
function applyMiddleware(...middlewares) {
return (createStore) => (...args) => {
var store = createStore(...args);
let dispatch = store.dispatch;
var middleApi = {
getState: store.getState,
dispatch: (action) => dispatch(action),
};
var middlewaresChain = middlewares.map((middleware) =>
middleware(middleApi)
);
dispatch = compose(...middlewaresChain)(store.dispatch);
return {
...store,
dispatch,
};
};
}
compose.js
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
以上就是我学习过程中学过的reduce知识,整理了一下,希望您看了会有收获!!