Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e183dca

Browse filesBrowse files
committed
update: remove caveats on this identity and private fields
1 parent 1def3e5 commit e183dca
Copy full SHA for e183dca

File tree

Expand file treeCollapse file tree

1 file changed

+10
-47
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+10
-47
lines changed

‎active-rfcs/0000-class-api.md

Copy file name to clipboardExpand all lines: active-rfcs/0000-class-api.md
+10-47Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ class MyComponent extends Vue {
142142
}
143143
```
144144

145+
#### Usage with Private Fields
146+
147+
Note that private fields are **NOT** reactive, because they are private to the class and thus cannot be inspected by framework code, which is required to create reactive state for them. Incidentally, they can be used to declare properties that should not be observed by Vue:
148+
149+
``` js
150+
class MyComponent extends Vue {
151+
#renderer = new 3DRenderer() // will not be observed by Vue
152+
}
153+
```
154+
145155
#### A Note on `[[Set]]` vs `[[Define]]`
146156

147157
The class field syntax uses `[[Define]]` semantics in both native and transpiled implementations (Babel already conforms to the latest spec and TS will have to follow suite). This means `count = 0` in the class body is executed with the semantics of `Object.defineProperty` and will always overwrite a property of the same name inherited from a parent class, regardless of whether it has a setter or not.
@@ -481,53 +491,6 @@ The decision to go with decorators for props in TypeScript is due to the followi
481491

482492
5. If users are using TypeScript, they already have decorators available to them via TypeScript's tool chain so unlike vanilla JavaScript there's no need for additional tooling.
483493

484-
## `this` Identity in `constructor`
485-
486-
In Vue 3 component classes, the `this` context in all lifecycle hooks and methods are in fact a Proxy to the actual underlying instance. This Proxy is responsible for returning proper values for the data, props and computed properties defined on the current component, and provides runtime warning checks. It is important for performance reasons as it avoids many expensive `Object.defineProperty` calls when instantiating components.
487-
488-
In practice, your code will work exactly the same - the only cases where you need to pay attention is if you are using `this` inside the native `constructor` - this is the only place where Vue cannot swap the identity of `this` so it will not be equal to the `this` exposed everywhere else:
489-
490-
``` js
491-
let instance
492-
493-
class MyComponent extends Vue {
494-
constructor() {
495-
super()
496-
instance = this // actual instance
497-
}
498-
499-
created() {
500-
console.log(this === instance) // false, `this` here is the Proxy
501-
}
502-
}
503-
```
504-
505-
In practice, there shouldn't be cases where you must use the `constructor`, so the best practice is to simply avoid it and always use component lifecycle hooks.
506-
507-
## Usage with Private Fields
508-
509-
Due to `this` being Proxies, this API won't work directly with [Private Class Fields](https://github.com/tc39/proposal-private-methods) (stage 3 proposal), because private fields by design are not exposed on Proxies of the original instance. So the following will not work:
510-
511-
``` js
512-
class Foo extends Vue {
513-
#count = 0
514-
created() {
515-
this.#count // Error because `this` is a Proxy
516-
}
517-
}
518-
```
519-
520-
The runtime is able to detect this type of Errors and provide appropriate warnings. We can expose the raw, original instance as a special property on the proxy (naming tentative):
521-
522-
``` js
523-
class Foo extends Vue {
524-
#count = 0
525-
created() {
526-
this.$self.#count // confirmed to work in Chrome 73
527-
}
528-
}
529-
```
530-
531494
## Two Ways of Doing the Same Thing
532495

533496
This may cause beginners to face a choice early on: to go with the object syntax, or the class syntax?

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.