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

Vue使用ref包装类实例触发私有成员访问错误的原因与解决

错误原因与解决方案

错误原因

ES6 私有字段(#name)采用词法作用域绑定规则:只有在声明该私有字段的类(Inner)内部,或由该类实例直接调用的方法中,才能合法访问私有字段。

Vue 的 ref 会对传入的对象创建响应式代理(Proxy),当你调用 outer.value.getInnerName() 时,getInnerName 方法中的 this 指向的是被 Proxy 包装后的 Outer 实例。此时调用 this.inner.getName(),JS 引擎会校验私有字段的访问上下文——由于调用链路经过了 Proxy 代理的外层对象,引擎判定当前访问并非来自 Inner 类允许的合法上下文,因此抛出 TypeError。

解决方案(仅修改 Outer 类)

方案1:用箭头函数定义 getInnerName

箭头函数没有独立的 this,会捕获定义时的原始 Outer 实例,避免 Proxy 代理影响 this 指向:

import { ref } from 'vue'
class Outer {
    inner: Inner = new Inner('aaa')
    // 改用箭头函数
    getInnerName = () => {
        return this.inner.getName()
    }
}
class Inner {
    #name: string
    constructor(name: string) {
        this.#name = name
    }
    getName() {
        return this.#name
    }
}
const outer = ref(new Outer())
console.log(outer.value.getInnerName()) // 正常输出 'aaa'

方案2:在构造函数中绑定 this

通过 bind 方法将 getInnerName 的 this 固定为原始 Outer 实例:

import { ref } from 'vue'
class Outer {
    inner: Inner = new Inner('aaa')
    constructor() {
        // 绑定this到当前实例
        this.getInnerName = this.getInnerName.bind(this)
    }
    getInnerName() {
        return this.inner.getName()
    }
}
class Inner {
    #name: string
    constructor(name: string) {
        this.#name = name
    }
    getName() {
        return this.#name
    }
}
const outer = ref(new Outer())
console.log(outer.value.getInnerName()) // 正常输出 'aaa'

内容的提问来源于stack exchange,提问作者肉蛋充肌

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:25:14