JavaScriptのプロパティおよびメソッド名の下線プレフィックス


240

JavaScriptの下線プレフィックスは、たとえばPythonのプライベートクラスメソッドのように、単なる規則ですか?

2.7 Pythonドキュメントから:

オブジェクトの内部以外からアクセスできない「プライベート」インスタンス変数は、Pythonには存在しません。ただし、ほとんどのPythonコードが従う規則があります。アンダースコアで始まる名前(_spamなど)は、APIの非公開部分として処理する必要があります(関数、メソッド、データメンバーのいずれであっても) 。

これはJavaScriptにも適用されますか?

たとえば、次のJavaScriptコードを見てください。

function AltTabPopup() {
    this._init();
}

AltTabPopup.prototype = {
    _init : function() {
        ...
    }
}

また、アンダースコアの接頭辞付き変数が使用されます。

    ...
    this._currentApp = 0;
    this._currentWindow = -1;
    this._thumbnailTimeoutId = 0;
    this._motionTimeoutId = 0;
    ...

慣習のみ?または、アンダースコアのプレフィックスの後ろにもっとありますか?


私の質問はこの質問と非常に似ていますが、JavaScriptの下線プレフィックスの重要性について賢くすることはできませんでした。


回答:


33

2019へようこそ!

接頭辞付き変数をプライベートにできるようにクラス構文を拡張する提案#が受け入れられたようです。Chrome 74にはこのサポートが付属しています。

_ 接頭辞付きの変数名は、慣例によりプライベートと見なされますが、依然としてパブリックです。

この構文は簡潔で直感的ですが、他のプログラミング言語とはかなり異なります。

すべてのUnicodeコードポイントの中からシギル#が選ばれたのはなぜですか?

  • @が最初のお気に入りでしたが、デコレータによって取得されました。TC39は、デコレータと民間の状態標識を交換することを検討しましたが、委員会は、トランスパイラーユーザーの既存の使用法に従うことを決定しました。
  • _は、既存のJavaScriptコードとの互換性の問題を引き起こします。これにより、識別子または(パブリック)プロパティ名の先頭で長い間_が許可されていました。

この提案は2017年7月にステージ3に達しました。それ以来、さまざまな代替案について広範な検討と長い議論が行われています。結局、この思考プロセスと継続的なコミュニティの関与により、このリポジトリでの提案に関する新たなコンセンサスが生まれました。そのコンセンサスに基づいて、実装はこの提案を進めています。

https://caniuse.com/#feat=mdn-javascript_classes_private_class_fieldsを参照してください


257

それは単なる慣習です。JavaScript言語は、アンダースコア文字で始まる識別子に特別な意味を与えません。

とは言っても、そのままの状態でカプセル化をサポートしていない言語では、これは非常に便利な規則です。誰かがクラスの実装を悪用するのを防ぐ方法はありませんが、少なくともそれによって意図が明確になり、そもそもそのような動作が間違っていることを文書化します。


4
うん。言語がそれを「サポート」していない場合でも、これは非常に便利な規則です。
JuhoVepsäläinen、2010

深刻な問題。jsfiddle.net/VmFSRあなたがそこに見ることができるように、値作成した名前は使用して、作成され、新しい値を付けることによってのみアクセス可能である_、私は何が起こっているのかを知ってみたいです!なぜそうではないのthis.nameですか?
Muhammad Umer 2013

1
@Muhammad Umer、私はあなたのコメントを理解しているかわかりません。console.log(someone._name = "Jean Dupont");はと同様に機能しconsole.log(someone.name);、プロパティの背後にあるアンダースコアで始まるメンバーを割り当てて評価します。ご覧のとおり、アンダースコアによるカプセル化は保証されていません:)
フレデリックハミディ2013

3
デフォルトでは、Visual Studioはこれを尊重する手助けをします。javascript IntelliSenseエンジンは、「this」変数を使用すると、オブジェクト内から「プライベート」プロパティを表示します。ただし、外部から呼び出されると、下線付きの属性はすべて非表示になります。
foxont​​herock

1
@Karhanga彼は2010年にこれに答えました-もちろん、10年間で状況は変化しました
Kenny Meyer

99

JavaScriptは実際には、クロージャー内のメンバーを非表示にする方法(Crockford)を通じて、カプセル化をサポートしています。そうは言っても、それは時々厄介であり、アンダースコアの規則は、一種のプライベートなものに使用するのにかなり良い規則ですが、実際に非表示にする必要はありません。


19
閉鎖を達成する方法を明確にするために賛成票を投じ、アンダースコアを言うことには反対票を投じます。だから私はどちらの方法にも投票しません:)
Jason

3
クロージャーでメンバーを非表示にすると、テストが困難になる場合があります。この記事をチェックしてください:適切に
良い.com / 2010/7 / Writing

4
@ジェイソン-ちょうど好奇心が強い、なぜあなたは悪い慣習を強調するのか?
タマシュのPap

5
@TamasPap-いくつかの理由がありますが、私の選択肢は次のとおりです。1)JSを他の言語のスタイルに強制する松葉杖2)アクセス可能であれば、それを使用します。アンダースコアは、外部のコードに散らばって入り込む可能性があります。3)新しいJSプログラマーを混乱させる。
Jason

9
クロージャーがあっても、いわゆる「プライベート」変数にアクセスすることは技術的にまだ可能です。_conventionは、少なくとも開発者に自己の責任で(またはそのようなことで)行うことを知らせます。
2013


10

「規約のみですか、それともアンダースコアプレフィックスの後ろにもっとありますか?」

プライバシー規約とは別に、特にURIアンカーマップで、アンダースコアプレフィックスが独立した引数に依存する引数にも使用されていることを認識できるようにしたいと思っていました。依存キーは常にマップを指します。

例(https://github.com/mmikowski/urianchorから ):

$.uriAnchor.setAnchor({
  page   : 'profile',
  _page  : {
    uname   : 'wendy',
    online  : 'today'
  }
});

ブラウザの検索フィールドのURIアンカーが次のように変更されました。

\#!page=profile:uname,wendy|online,today

これは、ハッシュの変更に基づいてアプリケーションの状態を駆動するために使用される規則です。


8

import/export現在ES6で仕事をしています。_ほとんどの関数がエクスポートされている場合でも、エクスポートされていない関数の前に付ける傾向があります。

(角度プロジェクトのように)クラスのみをエクスポートする場合、クラスはまったく必要ありません。

export class MyOpenClass{

    open(){
         doStuff()
         this._privateStuff()
         return close();
    }

    _privateStuff() { /* _ only as a convention */} 

}

function close(){ /*... this is really private... */ }

インポート/エクスポートがプライベートクラスメソッドのサポートを提供することはないと思います。つまり、クラスレベルで同様の機能をサポートしますが、含まれているメソッドを非表示にすることはできません。(つまり、含まれているすべてのメソッドは常にパブリックです)
bvdb 2018年

クラスをエクスポートし、内部関数を外部関数で呼び出します。これらの関数はプライベートです。
Nicolas Zozol 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.