实现 isReactive

isReactive判断传入的对象是否是reactive包裹的响应式对象

实现 isReactive 功能

单测

1
2
3
4
5
6
7
8
9
//reactivity/__test__/reactive.spec.ts
...
import { isReactive } from '../reactive'
it('isReactive', () => {
const user = { age: 10, name: '秋簌' }
const observed = reactive(user)
expect(isReactive(observed)).toBe(true)
expect(isReactive(user)).toBe(false)
})

实现单测

1
2
3
//reactivity/reactive.ts
...
export const isReactive = raw => !!raw['is_reactive']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//reactivity/baseHandler.ts
...
export const createGetter = (isReadonly = false) => {
return function get(target, key) {
if (key === 'is_reactive') {
return !isReadonly
}
/**嵌套转换 */
if (isObject(res)) {
return isReadonly ? readonly(res) : reactive(res)
}
const res = Reflect.get(target, key)
if (!isReadonly) {
track(target, key)
}
return res
}
}

重构代码

抽离 is_reactive 出来用枚举表示

1
2
3
4
5
6
//reactivity/reactive.ts
...
export const ReactiveFlags{
IS_REACTIVE:"__v_isReactive"
}
export const isReactive = raw => !!raw[ReactiveFlags.IS_REACTIVE]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//reactivity/baseHandler.ts
...
import { ReactiveFlags } from './reactive'
export const createGetter = (isReadonly = false) => {
return function get(target, key) {
if (key === ReactiveFlags.IS_REACTIVE) {
return !isReadonly
}
const res = Reflect.get(target, key)
/**嵌套转换 */
if (isObject(res)) {
return isReadonly ? readonly(res) : reactive(res)
}
if (!isReadonly) {
track(target, key)
}
return res
}
}

实现 isReadonly 功能

isReadonly判断传入的对象是否是readonly包裹的只读属性

单测

1
2
3
4
5
6
7
8
9
//reactivity/__test__/readonly.spec.ts
...
import { isReadonly } from '../reactive'
it('isReadonly', () => {
const user = { age: 10, name: '秋簌' }
const observed = reactive(user)
expect(isReadonly(observed)).toBe(true)
expect(isReadonly(user)).toBe(false)
})

实现单测

1
2
3
4
5
6
7
//reactivity/reactive.ts
...
export const ReactiveFlags{
IS_REACTIVE:"__v_isReactive",
IS_READONLY"__v_isReadonly"
}
export const isReadonly=raw=>!!raw[ReactiveFlags.IS_READONLY];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//reactivity/baseHandler.ts
...
import { ReactiveFlags } from './reactive'
export const createGetter = (isReadonly = 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 (isObject(res)) {
return isReadonly ? readonly(res) : reactive(res)
}
if (!isReadonly) {
track(target, key)
}
return res
}
}