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,提问作者肉蛋充肌
相关产品推荐
相关产品推荐

