isPlainObject函数是redux自己用来判断传递给reducer的action对象是一个plain object,也就是通过字面量方式或者Object构造函数的方式生成的对象,中间没有发生其他的继承情况,保持action对象是一个plain object的作用是,方便reducer进行处理,不用处理其他的情况(例如:promise/function/class实例等等),另一方面,也是方便的对状态进行记录或者回溯(比如说redux devtool工具里的action删除、跳过等操作)
/**
* @param {any} obj The object to inspect.
* @returns {boolean} True if the argument appears to be a plain object.
*/
export default function isPlainObject(obj) {
if (typeof obj !== 'object' || obj === null) return false
let proto = obj
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}
return Object.getPrototypeOf(obj) === proto
}
代码理解也不难,就是通过一个while循环拿到参数对象原型链的最后一个值,普通的对象while循环结束后proto的值是:Object.prototype,通过Object.create(null)生成的对象proto的值是:null
但是为什么不直接进行下面的判断呢?
return Object.getPrototypeOf(obj) === Object.prototype || Object.getPrototypeOf(obj) === null
这段代码仿佛和reduxcode的作用是一样的,我最开始也是不太理解,查看了官方github仓库下面的讨论后才了解到原因~~
redux的代码是为了防止一些边界情况的出现,对于一些cross-realm情况(例如跨frame访问变量时),使用我的代码就可能出现问题,比如说在一个frame里面调用父窗口的函数:
window.parent.someFunction(["hello", "world"])
在父窗口中有someFunction的定义:
function someFunction(arg) {
if (arg instanceof Array) {
// ... operate on the array
}
}
这样调用并不会执行if语句的代码,因为两段代码所处的javascript执行环境是不一样的,每个frame都有自己的执行环境,他们也不会共享原型链,也就是说两个执行环境中的Array Object构造函数都是不等的,那么if语句的判断就为false,这个数组并不是继承的父窗口执行环境里的Array。
这种情况下使用我的代码进行plain object判断自然也会出现问题。像其他的一些情况,例如不同的window窗口都算是处于不同的javascript执行环境~~
发现错误请留言告诉我~~~
本文详细解析了Redux中的isPlainObject函数,该函数用于判断传给reducer的action是否为纯对象,以简化reducer处理流程并方便状态记录与回溯.同时对比了一种替代实现方式,并解释了Redux采用当前实现的原因,尤其是在处理跨域或不同执行环境时的边界情况.
1227

被折叠的 条评论
为什么被折叠?



