Skip to content

Why are underscore prefixes for internal methods of a React component considered bad? #1024

Closed
@ttmarek

Description

@ttmarek
Contributor

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

lencioni commented on Aug 19, 2016

@lencioni
Contributor

They give people a false sense of "private"ness that could lead to bugs.

ttmarek

ttmarek commented on Aug 19, 2016

@ttmarek
ContributorAuthor

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

ljharb commented on Aug 19, 2016

@ljharb
Collaborator

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

ttmarek commented on Aug 19, 2016

@ttmarek
ContributorAuthor

npm broke node once by removing an underscore-prefixed variable

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

ljharb commented on Aug 19, 2016

@ljharb
Collaborator

@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

ttmarek commented on Aug 20, 2016

@ttmarek
ContributorAuthor

@ljharb So, in other words: underscore prefixed methods might confuse programmers from other languages into thinking that JavaScript supports private methods. Right?

ljharb

ljharb commented on Aug 20, 2016

@ljharb
Collaborator

That, or programmers who think that convention is the same as privacy.

ttmarek

ttmarek commented on Aug 20, 2016

@ttmarek
ContributorAuthor

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

lencioni commented on Aug 20, 2016

@lencioni
Contributor

I think so. I'd be happy to merge a PR that does that.

ljharb

ljharb commented on Aug 20, 2016

@ljharb
Collaborator

Sure, more helpful info is always good.

ericelliott

ericelliott commented on Aug 26, 2016

@ericelliott

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:

Newbies don't know what it means. Experienced developers think they know what they're doing and the underscore doesn't apply to them.

Admit it. You've done that, too.

mpj

mpj commented on Aug 26, 2016

@mpj

I think @lencioni is perfectly correct by saying

They give people a false sense of "private"ness that could lead to bugs.

... 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

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mpj@ljharb@StokeMasterJack@lencioni@kmmbvnr

        Issue actions

          Why are underscore prefixes for internal methods of a React component considered bad? · Issue #1024 · airbnb/javascript