实现isReactive和isReadonly
isReactive实现
先上测试用例(其实这个测试用例也是reactive.spec.ts中追加的两个):
import { isReactive, reactive } from "../reactive"
describe('reactive',()=>{
    it('happy path',()=>{
        const original = {foo:1}
        const observed = reactive(original)
        expect(observed).not.toBe(original)
        expect(observed.foo).toBe(1)
        expect(isReactive(observed)).toBe(true)
        expect(isReactive(original)).toBe(false)
    })
})
实现:
1 reactive.ts中导出isReactive方法
2 利用isReactive传入的对象,调用对象中特定设置的一个属性__v_isReactive,如果这个对象是响应式对象,就会走get函数
3 我们可以在get函数中判断key值,如果为__v_isReactive的话,就返回他不是readonly


优化
对于这种__v_isReactive属性,我们可以使用枚举,让我们在别的地方降低书写错误
修改如下


isReadonly实现
有了isReactive的实现,那isReadonly也就水到渠成了,测试案例

实现上基本和isReactive一样
reactive.ts


最终:
reactive.ts代码
import { mutableHandlers, readonlyHandlers } from "./baseHandlers"
export const enum ReactiveFlags {
    IS_REACTIVE = "__v_isReactive",
    IS_READONLY = "__v_isReadonly"
}
export function reactive(raw){
    return createReactiveObject(raw,mutableHandlers)
}
export function readonly(raw){
    return createReactiveObject(raw,readonlyHandlers)
}
export function isReactive(value){
    return !!value[ReactiveFlags.IS_REACTIVE]
}
export function isReadonly(value){
    return !!value[ReactiveFlags.IS_READONLY]
}
function createReactiveObject(target,baseHandlers){
    return new Proxy(target,baseHandlers)
}
baseHandlers.ts
import { track, trigger } from "./effect"
import { ReactiveFlags } from "./reactive"
const get = createGetter()
const set = createSetter()
const readonlyGet = createGetter(true)
function createGetter(isReadonly = false){
    return function get(target,key){
        const res = Reflect.get(target,key)
        if(key === ReactiveFlags.IS_REACTIVE) {
            return !isReadonly
        }
        if(key === ReactiveFlags.IS_READONLY) {
            return isReadonly
        }
        if(!isReadonly) {
            track(target,key)
        }
        return res
    }
}
function createSetter() {
    return function set(target,key,value){
        const res = Reflect.set(target,key,value)
        trigger(target,key)
        return res
    }
}
export const mutableHandlers = {
    get:get,
    set:set
}
export const readonlyHandlers = {
    get:readonlyGet,
    set(target,key,value){
        console.warn(`key:${key} set 失败 因为 target 是readonly`,target)
        return true
    }
}



















