下划线前缀在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中下划线前缀的重要性。


当前回答

欢迎来到2019年!

似乎一个扩展类语法以允许#前缀变量为私有的提议被接受了。Chrome 74船与此支持。

_前缀变量名按照惯例被认为是私有的,但仍然是公共的。

This syntax tries to be both terse and intuitive, although it's rather different from other programming languages. Why was the sigil # chosen, among all the Unicode code points? @ was the initial favorite, but it was taken by decorators. TC39 considered swapping decorators and private state sigils, but the committee decided to defer to the existing usage of transpiler users. _ would cause compatibility issues with existing JavaScript code, which has allowed _ at the start of an identifier or (public) property name for a long time. This proposal reached Stage 3 in July 2017. Since that time, there has been extensive thought and lengthy discussion about various alternatives. In the end, this thought process and continued community engagement led to renewed consensus on the proposal in this repository. Based on that consensus, implementations are moving forward on this proposal.

= mdn-javascript_classes_private_class_fields看到https://caniuse.com/壮举

其他回答

欢迎来到2019年!

似乎一个扩展类语法以允许#前缀变量为私有的提议被接受了。Chrome 74船与此支持。

_前缀变量名按照惯例被认为是私有的,但仍然是公共的。

This syntax tries to be both terse and intuitive, although it's rather different from other programming languages. Why was the sigil # chosen, among all the Unicode code points? @ was the initial favorite, but it was taken by decorators. TC39 considered swapping decorators and private state sigils, but the committee decided to defer to the existing usage of transpiler users. _ would cause compatibility issues with existing JavaScript code, which has allowed _ at the start of an identifier or (public) property name for a long time. This proposal reached Stage 3 in July 2017. Since that time, there has been extensive thought and lengthy discussion about various alternatives. In the end, this thought process and continued community engagement led to renewed consensus on the proposal in this repository. Based on that consensus, implementations are moving forward on this proposal.

= mdn-javascript_classes_private_class_fields看到https://caniuse.com/壮举

“唯一的约定吗?或者下划线前缀后面还有其他含义?”

除了隐私约定之外,我还想帮助大家认识到,下划线前缀也用于依赖于独立参数的参数,特别是在URI锚点映射中。依赖键总是指向一个映射。

示例(来自https://github.com/mmikowski/urianchor):

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

浏览器搜索字段的URI锚被更改为:

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

这是一种约定,用于基于散列更改驱动应用程序状态。

导入/导出现在在ES6中做这项工作。如果我的大部分函数都导出了,我仍然倾向于在未导出的函数前面加上_。

如果你只导出一个类(比如在angular项目中),它根本就不需要。

export class MyOpenClass{

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

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

}

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

JSDoc 3允许您使用@access private标记(以前是@private标记)注释您的函数,这对于向其他开发人员传播您的意图也很有用—http://usejsdoc.org/tags-access.html

JavaScript实际上支持封装,通过在闭包中隐藏成员的方法(Crockford)。也就是说,它有时很麻烦,下划线约定是一个很好的约定用于私有的东西,但实际上你不需要隐藏。