javascript - Why is "attempted to set private field on non-instance only" error firing when using a data membe

I'm writing a class using private fields:export default class Foo {#bar;init(number){this.#bar =

I'm writing a class using private fields:

export default class Foo {
    #bar;
    init(number){
        this.#bar = number;
    }
    getBar(){
        return this.#bar;
    }
}

I'm testing it in a vue ponent:

<template>
  <div class="hello">
    <div>{{bar}}</div>
  </div>
</template>

<script>
import Foo from '../api/foo.js';
export default {
  data(){
    return {
      foo: new Foo(),
      bar: '',
    }
  },
  mounted() {
    // doesn't work
    this.foo.init(2);
    this.bar = this.foo.getBar();
  },
}
</script>

But this code throws the following error:

Uncaught TypeError: attempted to set private field on non-instance
    at _classExtractFieldDescriptor (classExtractFieldDescriptor.js?06d5:3)
    at _classPrivateFieldSet (classPrivateFieldSet.js?9bd1:4)
    at Proxy.init (foo.js?c8b1:8)
    at Proxy.mounted (HelloWorld.vue?fdab:18)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6990)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:6999)
    at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?5c40:2270)
    at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:7191)
    at render (runtime-core.esm-bundler.js?5c40:5142)
    at mount (runtime-core.esm-bundler.js?5c40:3477)

It seems that I can't use my init() method on this.foo which is declared in my vue data member, but I can use a local variable and then set my data member:

  mounted() {
    // works
    const foo = new Foo();
    foo.init(2);
    this.bar = foo.getBar();
  },

Is this a normal behavior? Is there any ways to have this.foo.init(2) work?

I'm writing a class using private fields:

export default class Foo {
    #bar;
    init(number){
        this.#bar = number;
    }
    getBar(){
        return this.#bar;
    }
}

I'm testing it in a vue ponent:

<template>
  <div class="hello">
    <div>{{bar}}</div>
  </div>
</template>

<script>
import Foo from '../api/foo.js';
export default {
  data(){
    return {
      foo: new Foo(),
      bar: '',
    }
  },
  mounted() {
    // doesn't work
    this.foo.init(2);
    this.bar = this.foo.getBar();
  },
}
</script>

But this code throws the following error:

Uncaught TypeError: attempted to set private field on non-instance
    at _classExtractFieldDescriptor (classExtractFieldDescriptor.js?06d5:3)
    at _classPrivateFieldSet (classPrivateFieldSet.js?9bd1:4)
    at Proxy.init (foo.js?c8b1:8)
    at Proxy.mounted (HelloWorld.vue?fdab:18)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6990)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:6999)
    at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?5c40:2270)
    at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:7191)
    at render (runtime-core.esm-bundler.js?5c40:5142)
    at mount (runtime-core.esm-bundler.js?5c40:3477)

It seems that I can't use my init() method on this.foo which is declared in my vue data member, but I can use a local variable and then set my data member:

  mounted() {
    // works
    const foo = new Foo();
    foo.init(2);
    this.bar = foo.getBar();
  },

Is this a normal behavior? Is there any ways to have this.foo.init(2) work?

Share Improve this question edited Aug 31, 2021 at 12:48 Raphaël asked Aug 31, 2021 at 12:41 RaphaëlRaphaël 1902 silver badges13 bronze badges 3
  • 1 Can't reproduce your problem. Everything seems to be working fine here: codesandbox.io/s/petent-khorana-ij02n?file=/src/App.vue – Mythos Commented Aug 31, 2021 at 15:00
  • Thank you very much for your time, I'll look into it tomorrow. Maybe I misconfigured something. – Raphaël Commented Aug 31, 2021 at 15:51
  • indeed, it works with vue2 but not with vue3 : codesandbox.io/s/agitated-chatterjee-uohy9?file=/src/App.vue – Raphaël Commented Sep 1, 2021 at 8:13
Add a ment  | 

1 Answer 1

Reset to default 6

Thanks to Mythos, it appeared that it works with vue2 (example here) but not with vue3 (example here). After some digging, it looks like private members break proxies and that Proxy were introduced in vue3 for ponents' data function :

When we return a plain JavaScript object from a ponent's data function, Vue will wrap that object in a Proxy (opens new window)with handlers for get and set. Proxies were introduced in ES6 and allow Vue 3 to avoid some of the reactivity caveats that existed in earlier versions of Vue.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744246367a4564952.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信