最近在读Redux源码,现将自己实现的代码和理解贴上,后期再补充详细~
/*** 判断某个对象是否是一个plain-object* @param {*} obj */
function isPlainObject(obj) {if (typeof obj !== "object") {return false;}return Object.getPrototypeOf(obj) === Object.prototype;
}/*** 得到一个指定长度的随机字符串* @param {*} length */
function getRandomString(length) {return Math.random().toString(36).substr(2, length).split("").join(".")
}/*** 实现createStore的功能* @param {*} reducer 接收reducer处理器* @param {*} defaultState 初始化的状态值*/
export function createStore(reducer, defaultState, enhancer) {// 判断是否传入defaultStateif (typeof defaultState === 'function' && typeof enhancer === 'undefined') {enhancer = defaultStatedefaultState = undefined}// 判断是否传入enhancer且为函数if (typeof enhancer !== 'undefined') {if (typeof enhancer !== 'function') {throw new Error('Expected the enhancer to be a function.')}return enhancer(createStore)(reducer, defaultState)}let currentReducer = reducer, //当前使用的reducercurrentState = defaultState; //当前仓库中的状态const listeners = []; //记录所有的监听器(订阅者)function dispatch(action) {//验证action是否是平面对象if (!isPlainObject(action)) {throw new TypeError("action must be a plain object");}//验证action的type属性是否存在if (action.type === undefined) {throw new TypeError("action must has a property of type");}currentState = currentReducer(currentState, action)//运行所有的订阅者(监听器)for (const listener of listeners) {listener();}};function getState() {return currentState;};// 发布订阅模式function subscribe(listener) {listeners.push(listener);let isRemove = false;return function () {if (isRemove) return;//将listener从数组中移除const index = listeners.indexOf(listener);listeners.splice(index, 1);isRemove = true;}}//创建仓库时,需要分发一次初始的actiondispatch({type: `@@redux/INIT${getRandomString(7)}`});return {dispatch,getState,subscribe}
}