在翻看immer.js的源码(v0.4.0)时,发现其中有一个方法用来判断给定值,是否可以创建代理对象,源码如下
function isProxyable(value) {
if (!value) return false
if (typeof value !== "object") return false
if (Array.isArray(value)) return true
const proto = Object.getPrototypeOf(value)
return (proto === proto) === null || Object.prototype
}
最后的语句死活看不懂,调试后也是返回Object.prototype
, 最后交给ChatGPT来解释,gpt给的答案是源码写错了, 应该是判断proto === null || proto === Object.prototype
;
对于判断proto === Object.prototype
是能理解的,因为字面量的对象,原型就是Object.prototype
, 但是为什么要增加proto === null
的判断呢?
说明Object.create(null)
也是能创建出类似字面量对象那样的值,尝试如下代码
const v = Object.create(null); // {}
v.name = 'v'; // { name: 'v' }
Object.getPrototypeOf(v); // null
因此,对于类似字面量对象的值,其原型有两种可能:
Object.prototype
null
对于immer.js v0.4.0版本,创建代理对象而言,目标对象仅限于Plain Object,因为immer.js要解决的问题就是plain object的数据更新问题,不解决原型链复杂的对象更新问题。