属性和方法名称的下划线前缀仅仅是一种约定吗?

IT技术 javascript scope naming-conventions
2021-02-08 14:12:16

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

6个回答

那只是一个约定。Javascript 语言没有赋予以下划线字符开头的标识符任何特殊含义。

也就是说,对于不支持开箱即用封装的语言来说,这是一个非常有用的约定尽管没有办法阻止某人滥用您的类的实现,但至少它确实阐明了您的意图,并且首先将此类行为记录为错误

对。即使语言不“支持”它,它也是一个非常方便的约定。
2021-03-13 14:12:16
@Karuhanga 他早在 2010 年就回答了这个问题——当然 10 年来情况发生了变化
2021-03-13 14:12:16
@Muhammad Umer,我不确定我是否理解您的评论。console.log(someone._name = "Jean Dupont");和 一样有效console.log(someone.name);,它同时分配和评估属性后面的下划线前缀成员。如您所见,不能保证通过下划线进行封装:)
2021-03-24 14:12:16
默认情况下,Visual Studio 会尝试帮助您尊重这一点。当使用“this”变量时,javascript IntelliSense 引擎会从对象内部向您显示“私有”属性。但是,当从外部调用时,它隐藏了所有带下划线的属性。
2021-03-27 14:12:16
严重的问题。jsfiddle.net/VmFSR正如您在那里看到的,值创建的名称只能通过添加新值的前缀来访问,创建的,使用_我很想知道发生了什么!?为什么this.name不是呢?
2021-03-30 14:12:16

JavaScript 实际上确实支持封装,通过一种将成员隐藏在闭包中的方法(Crockford)。也就是说,它有时很麻烦,而且下划线约定是一个很好的约定,可用于某种私有的事物,但您实际上并不需要隐藏。

赞成澄清如何实现闭包,反对说下划线是好的惯例。所以我不会投票:)
2021-03-17 14:12:16
即使有闭包,在技术上仍然可以访问所谓的“私有”变量。_convention 至少让开发人员知道这样做的风险由他们自己承担(或类似的事情)。
2021-03-18 14:12:16
@TamasPap - 几个原因,但只是我的选择:1) 将 JS 强制转换为其他语言风格的拐杖 2) 如果它可以访问,它将被使用。下划线可以乱扔和复杂外部代码。3) 对新的 JS 程序员造成混淆。
2021-03-26 14:12:16
在闭包中隐藏成员有时会阻碍可测试性。查看这篇文章:attributelygood.com/2010/7/Writing-Testable-JavaScript
2021-04-04 14:12:16
@Jason - 只是好奇,为什么你认为下划线是一个糟糕的约定?
2021-04-06 14:12:16

欢迎来到 2019!

似乎接受了扩展类语法以允许前缀变量为私有提议#Chrome 74附带此支持。

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

这种语法试图既简洁又直观,尽管它与其他编程语言有很大不同。

为什么在所有 Unicode 代码点中选择了符号 #?

  • @ 是最初的最爱,但它被装饰者拿走了。TC39 考虑过交换装饰器和私有状态符号,但委员会决定遵循转译器用户的现有用法。
  • _ 会导致与现有 JavaScript 代码的兼容性问题,这在很长一段时间内都允许在标识符或(公共)属性名称的开头使用 _。

该提案于 2017 年 7 月进入第 3 阶段。从那时起,人们对各种替代方案进行了广泛的思考和长时间的讨论。最后,这个思考过程和持续的社区参与导致对该存储库中的提案重新达成共识。基于这一共识,该提案的实施正在向前推进。

https://caniuse.com/#feat=mdn-javascript_classes_private_class_fields

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

“只有约定?还是下划线前缀后面还有更多?”

除了隐私约定,我还想帮助大家意识到下划线前缀也用于依赖于独立参数的参数,特别是在 URI 锚映射中。从属键始终指向映射。

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

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

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

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

这是用于根据哈希更改驱动应用程序状态的约定。