今天要实现的这俩功能比较简单 ,一个是浅层次的readonly,一个是判断是不是一个Proxy对象,一起来写写吧
目录
shallowReadonly
shallowReadonly也就是只对最外层做readonly,内部如果还要对象属性,不做readonly处理
那么我们如果是shallow的话,就不用递归了,借鉴isReaonly写法,我们也传入一个变量用于检验是否是shallow
这是我们写的单测, 最下面两行是实现的功能
function createGetter(isReadonly = false, isShallow = false) {
return function get(target, key) {
if (key === reactiveFlags.IS_REACTIVE) {
return !isReadonly
} else if (key === reactiveFlags.IS_READONLY) {
return isReadonly
}
const res = Reflect.get(target, key)
if (isShallow) {
return res
}
if (isObject(res)) {
return isReadonly ? readonly(res) : reactive(res)
}
if (!isReadonly) {
track(target, key)
}
return res
}
}
我们知道readonly与reactive区别是readonly不做依赖收集,而shallow与readonly区别是,我们不需要再递归了,因此,我们传入一个shallow变量,当为true的时候直接返回res即可,不需要再递归将深层的对象属性也变成readonly
这样我们再创建一个shallowReadonly的方法来让它的get方法变成这样即可
const getShallowReadonly = createGetter(true, true)
export const readonlyHandler = {
get: getReadonly,
set(target, key, value) {
console.warn(`${key}不能set 因为target 是readonly`, target)
return true
}
}
export const shallowReaonlyHandler = extend({}, readonlyHandler,
{ get: getShallowReadonly }
)
这里的extend方法是Object.assign,因为shallowReadonly与readonly的set方法一样,因此不要再写一遍set方法了
isProxy
是否是一个Proxy对象,这个很简单就可以实现,只需要判断它是否是一个reactive或者一个readonly即可
以下是readonly以及reactive要实现的单元测试
export function isProxy(value) {
return isReactive(value) || isReadonly(value)
}
我们直接调用isReactive与isReadonly即可,如果是其中之一那就是proxy,如果不是那就不是Proxy