https://lea.verou.me/2023/04/private-fields-considered-harmful/ Skip to the content Search [mark] Lea Verou Life at the bleeding edge (of web standards) Menu * Projects * Speaking * Publications * Press * Interviews * About Search Search for: [ ] [Search] Close search Close Menu * Projects * Speaking * Publications * Press * Interviews * About * @leaverou on Twitter * GitHub * LinkedIn * Dribbble * CodePen * @leaverou@front-end.social Categories Articles Thoughts JS private class fields considered harmful * Post author By Lea Verou * Post date April 28, 2023 * No Comments on JS private class fields considered harmful Reading Time: 2 minutes Today I mourn. What am I mourning? Encapsulation. At least in my projects. As a library author, I've decided to avoid private class fields from now on and gradually refactor them out of my existing libraries. Why did I make such a drastic decision? It all started a few days ago, when I was building a Vue 3 app that used Color.js Color objects. For context, Vue 3 uses proxies to implement its reactivity system, just like Mavo did back in 2016 (the first one to do so as far as I'm aware). I was getting several errors and upon tracking them down I had a very sad realization: instances of classes that use private fields cannot be proxied. I will let that sink in for a bit. Private fields, proxies, pick one, you can't have both. Here is a reduced testcase illustrating the problem. [image] Basically, because a Proxy creates a different object, it breaks both strict equality (obj1 === obj2), as well as private properties. MDN even has a whole section on this. Unfortunately, the workaround proposed is no help when proxies are used to implement reactivity, so when I tried to report this as a Vue bug, it was (rightly) closed as wontfix. It would not be possible to fix this in Mavo either, for the same reason. I joined TC39 fairly recently, so I was not aware of the background when proxies or private class fields were designed. Several fellow TC39 members filled me in on the discussions from back then. A lot of the background is in this super long thread, some interesting tl;drs as replies to my tweet: So it turns out that if you use private class fields, your instances are buggy when proxied . See https://t.co/vversOncPK That's ...very unfortunate. It means you cannot use these objects in @vuejs for example (Vue testcase: https://t.co/fbLDhJ7xWp ) pic.twitter.com/9feLO10srs -- Lea Verou (@LeaVerou) April 24, 2023 After a lot of back and forth, I decided I cannot justify using private properties going forwards. The tradeoff is simply not worth it. There is no real workaround for proxy-ability, whereas for private fields there is always private-by-convention. Does it suck? Absolutely. However, a sucky workaround is better than a nonexistent workaround. Also, I control the internal implementation of my classes, whereas proxying happens by other parties. As a library user, it must be incredibly confusing to have to deal with errors about access to private fields in a class you did not write. This was one of the saddest PRs I have ever written https:// github.com/LeaVerou/color.js/pull/306. It feels like such a huge step backwards. I've waited years for private fields to be supported everywhere and relished when they got there. I was among the first library authors to adopt them in library code, before a lot of tooling even parsed them properly (and some still don't). Sure, they were kind of annoying to use (you usually want protected, i.e. visible to subclasses, not actually private), but they were better than nothing. I was not joking in the first paragraph; I am literally grieving. I may still use private fields on a case by case basis, where I cannot imagine objects being proxied being very useful, for example in web components. But from now on I will not reach to them without thought, like I have been for the past couple of years. * Tags architecture, JavaScript, JS, TC39 --------------------------------------------------------------------- - Contrast Ratio has a new home -- and this is great news! --------------------------------------------------------------------- * @leaverou on Twitter * GitHub * LinkedIn * Dribbble * CodePen * @leaverou@front-end.social Buy my book! CSS Secrets book cover Search for: [ ] [Search] Categories * Articles (35) * Benchmarks (2) * CSS WG (3) * News (16) * Original (81) * Personal (38) * Rants (13) * Releases (36) * Replies (6) * Speaking (12) * Thoughts (21) * Tips (52) * Tutorials (5) * Uncategorized (4) Carbon ads Recent Posts * JS private class fields considered harmful * Contrast Ratio has a new home -- and this is great news! * Position Statement for the 2022 W3C TAG Election * State of CSS 2022 now open! * On ratings and meters * Help design the State of CSS Survey 2022! * What is the best way to mark up an exclusive button group? * Introducing Rety: live coding, without the stress * Releasing Color.js: A library that takes color seriously * On Yak Shaving and , a new HTML element for Markdown (c) 2023 Lea Verou Powered by WordPress To the top | Up |