实现 isReactive 和 isReadonly

在本小节中,我们将会实现 isReactive 和 isReadonly 这两个 API

1. isReactive 测试样例

// reactive.spec.ts
it('happy path', () => {
    // other code ...
    // 加入 isReactive 判断
    expect(isReactive(observed)).toBe(true)
    expect(isReactive(original)).toBe(false)
})

2. isReactive 实现

这个该如何实现呢,其实也是非常简单的:

// reactive.ts

// other code ...

export const enum ReactiveFlags {
  IS_REACTIVE = '__v_isReactive',
}

// other code ...

export function isReactive(raw) {
  // 这里为什么需要取反,这是因为如果是一个 original Object 的话,是不会进入 proxy getter 的
  // 这里的就会返回一个 undefined,双重取反强制转换为 boolean
  return !!raw[ReactiveFlags.IS_REACTIVE]
}

测试之后就跑通了

3. isReadonly 测试样例

// readonly.spec.ts
it('happy path', () => {
    // other code ...

    // [isReadonly]
    expect(isReadonly(wrapped)).toBe(true)
    expect(isReadonly(original)).toBe(false)
})

4. isReadonly 实现

这个实现也是很简单的,仿照 isReactive 的实现:

// reacive.ts

// other code ...

export const enum ReactiveFlags {
  IS_REACTIVE = '__v_isReactive',
  // 添加枚举
  IS_READONLY = '__v_isReadonly',
}

// other code ...


// 添加 API
export function isReadonly(raw) {
  return !!raw[ReactiveFlags.IS_READONLY]
}
// baseHandlers.ts

// other code ...

function createGetter(isReadonly = false) {
  return function get(target, key, receiver) {
    // 进行判断
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly
    }
    // other code ...
  }
}

// other code ...

这个时候再进行测试发现就可以通过了