Closed
Description
The third bullet under react#methods says:
Do not use underscore prefix for internal methods of a React component.
I was just wondering what the reasoning behind this was?
The third bullet under react#methods says:
Do not use underscore prefix for internal methods of a React component.
I was just wondering what the reasoning behind this was?
Activity
lencioni commentedon Aug 19, 2016
They give people a false sense of "private"ness that could lead to bugs.
ttmarek commentedon Aug 19, 2016
Okay. Even though JavaScript doesn't support private variables, I still think the underscores help communicate the programmer's intent. If possible, @lencioni could you give an example of this false sense of "private"ness that lead to a bug? Or maybe a scenario where the underscores would confuse another programmer and lead them astray. I'm not disagreeing with you, I just want to have a better understanding of how this rule came about.
ljharb commentedon Aug 19, 2016
Private means inaccessible. Your intent to privacy is irrelevant if the value is reachable, ie public.
For example, npm broke node once by removing an underscore-prefixed variable.
ttmarek commentedon Aug 19, 2016
If the variable wasn't prefixed they would have used it either way, and node would have still broke. When a meant-to-be-private variable is prefixed with an underscore there is at least one line of defence (a weak one, granted) preventing its use. Whereas when a meant-to-be-private variable isn't prefixed with an underscore, there is no line of defence (not even a weak one).
ljharb commentedon Aug 19, 2016
@ttmarek yes, but had they not prefixed it with an underscore, nobody would have been fooled into thinking it was actually private, and there would have been test coverage, and changing it would have prompted a semver-major version bump.
An underscore is in no way, whatsoever, a line of defense - it's just an incorrect assumption some developers make about a language that simply does not have the concept of privacy outside of closures.
ttmarek commentedon Aug 20, 2016
@ljharb So, in other words: underscore prefixed methods might confuse programmers from other languages into thinking that JavaScript supports private methods. Right?
ljharb commentedon Aug 20, 2016
That, or programmers who think that convention is the same as privacy.
ttmarek commentedon Aug 20, 2016
Okay, cool. Thanks @ljharb, I see what you're getting at. Do you think its worth adding a short blurb about this under the third bullet in react#methods?
lencioni commentedon Aug 20, 2016
I think so. I'd be happy to merge a PR that does that.
ljharb commentedon Aug 20, 2016
Sure, more helpful info is always good.
ericelliott commentedon Aug 26, 2016
My favorite reason:
Private stuff tends to change without warning, and without advertising as a breaking change.
The problem with that is that a lot of code could break without warning, because EVERYBODY ignores underscores:
Admit it. You've done that, too.
mpj commentedon Aug 26, 2016
I think @lencioni is perfectly correct by saying
... but I'd like to elaborate on why.
In programming languages in general, the point of having a private property (as opposed to having all properties public) is so that you can trust a private variable not to be changed by outside code, unlike public properties which you need to assume can be changed by outside code at any time.
If you're absolutely hell bent on using inheritance in JavaScript, you don't have private properties. It is not a feature of inheritance in JavaScript. Everything is public. The logical thing to do is therefore to treat every property as a public property (because it is) - your code needs to assume that it can change at any time.
You can call a property _myProperty or __DONTFUCKINGCHANGEmyProperty but that doesn't make that property private. It's public. Private does not exist in the object composition model that you have chosen. You're trying to reap the benefits of a feature that you do not have. If you write your code in a way that assumes that your public-property-with-special-name-convetion does not change, you're just fooling yourself. The fucker can change at any moment, just like any other of your properties.
(Sidenote: This is React, and the following is not an option there, but in general, unless you need to create more than 50000 items per second, I personally think that you should consider using factory functions (https://www.youtube.com/watch?v=ImwrezYhw4w) instead of inheritance for creating objects. They have real privacy and do not have this problem)
119 remaining items