You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3响应式中IS_REACTIVE标记何时被设置为true?

Vue3响应式中IS_REACTIVE标记的实现逻辑

首先要明确:IS_REACTIVE这类标记并不是直接添加到目标对象(target)本身的,而是通过Proxy的拦截器动态返回的——这就是你用hasOwnProperty查不到该属性,但直接取值能得到true的核心原因。

在createReactiveObject函数创建Proxy实例时,会传入对应的拦截器handler(比如创建普通响应式对象用的mutableHandlers),这个handler的get方法专门处理了ReactiveFlags相关的查询逻辑,核心代码来自reactivity包的baseHandlers.ts:

const get = /*#__PURE__*/ createGetter()

function createGetter(isReadonly = false, shallow = false) {
  return function get(target: Target, key: string | symbol, receiver: object) {
    // 优先处理ReactiveFlags的查询
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly
    } else if (key === ReactiveFlags.RAW) {
      return target // 返回原始对象
    }
    // ...其他属性读取的响应式逻辑
  }
}

当你访问target[ReactiveFlags.IS_REACTIVE]时,这里的target其实是Proxy实例(而非原始对象),会触发Proxy的get拦截器:匹配到ReactiveFlags.IS_REACTIVE这个key后,直接根据当前是否为只读对象返回对应布尔值——对于reactive创建的对象,isReadonly为false,所以返回true。

而调用target.hasOwnProperty(ReactiveFlags.IS_REACTIVE)时,同样会被Proxy拦截,最终查询的是原始对象是否拥有该属性,显然原始对象并没有这个标记,因此返回false。

回到你贴出的代码片段:

if (
    target[ReactiveFlags.RAW] &&
    !(isReadonly && target[ReactiveFlags.IS_REACTIVE])
  ) {
    console.log('keys ', target.hasOwnProperty(ReactiveFlags.IS_REACTIVE)) // 'keys ' false
    console.log(
      'target[ReactiveFlags.IS_REACTIVE] ',
      target[ReactiveFlags.IS_REACTIVE]
    ) // 'target[ReactiveFlags.IS_REACTIVE] ' true

    return target
  }

这里的target是Proxy实例,两种不同的查询方式触发了不同的拦截逻辑,才出现了看似矛盾的结果。

总结:

  • IS_REACTIVE标记从未被“添加”到目标对象上
  • 它是通过Proxy的get拦截器,在被访问时动态计算并返回的
  • 对应的处理逻辑在baseHandlers.ts的createGetter函数中

内容的提问来源于stack exchange,提问作者Bippan Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:10:02