JavaScript中属性和方法名称的下划线前缀

Ken*_*yer 216 javascript scope naming-conventions

JavaScript中的下划线前缀只是一个约定,例如在Python私有类方法中是什么?

从2.7 Python文档:

Python中不存在除了从对象内部访问之外无法访问的"私有"实例变量.但是,大多数Python代码都遵循一个约定:前缀为下划线的名称(例如_spam)应被视为API的非公共部分(无论是函数,方法还是数据成员) .

这也适用于JavaScript吗?

以此JavaScript代码为例:

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

AltTabPopup.prototype = {
    _init : function() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,使用下划线前缀变量.

    ...
    this._currentApp = 0;
    this._currentWindow = -1;
    this._thumbnailTimeoutId = 0;
    this._motionTimeoutId = 0;
    ...
Run Code Online (Sandbox Code Playgroud)

只有会议?或者下划线前缀后面还有更多?


我承认我的问题与这个问题非常相似,但它并没有让人更聪明地了解JavaScript中下划线前缀的重要性.

Fré*_*idi 244

那只是一个惯例.Javascript语言对以下划线字符开头的标识符没有任何特殊含义.

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

  • 对.即使语言不"支持"它,它也是一个非常方便的惯例. (4认同)
  • 默认情况下,Visual Studio会尝试帮助您尊重这一点.当使用"this"变量时,javascript IntelliSense引擎会在对象内部显示"私有"属性.但是,当从外部调用时,它会隐藏所有强调的属性. (3认同)

Zac*_*ach 97

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

  • 投票澄清如何实现关闭,投票表示下划线是一个很好的约定.所以我不会投票:) (19认同)
  • 即使有一个闭包,它在技术上*仍然可以访问所谓的"私有"变量._convention至少让开发者知道这样做是冒自己的风险(或类似的东西). (9认同)
  • @Jason - 只是好奇,你为什么要考虑强调一个不好的约定? (4认同)
  • @TamasPap - 有几个原因,但只是我的选择:1)一个拐杖强迫JS成为其他语言的风格2)如果它是可访问的,它将被使用.下划线可以乱丢外部代码.3)对新的JS程序员感到困惑. (4认同)
  • 隐藏在闭合中的成员有时会妨碍可测试性.看看这篇文章:http://www.adequatelygood.com/2010/7/Writing-Testable-JavaScript (3认同)
  • @Sorenly,像这样的黑客https://gist.github.com/sarink/7394867总是可行的.当然,你可以在框架中防范它.但如果有人能看到来源,他们当然可以找到方法. (3认同)
  • "...那些私密的东西,但你实际上并不需要*隐藏." ...或者你想要私密,也可以继承的东西.闭包中的变量不是可继承的AFAIK. (3认同)
  • @Jason如果你曾经和很多人一起编程,你会理解为什么这是一个很好的约定.传统上,它意味着某些东西是*私有*,但在JavaScript中它也意味着,*意识到,这可能会改变,所以你应该编写自己的方法/功能,这可能更稳定*.你试图避免(并传达给其他开发人员)的是,它可能在将来发生变化,而你不会为了向后兼容而维护它; 这意味着如果它破坏了他们的代码,他们就可以修复他们的东西了. (3认同)
  • @Jason嗯显然私人可以使用所有语言访问,为什么这是一个缺点? (2认同)

Kar*_*nga 18

欢迎来到2019!

似乎提出了扩展类语法的建议,以允许带_前缀的变量名称为public和带#前缀的变量名称(已接受private)。Chrome 74 附带此支持。


phi*_*bin 13

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


Sam*_*iza 9

"只有约定?或者下划线前缀后面还有更多?"

除了隐私约定之外,我还想帮助提高认识,即下划线前缀也用于依赖于独立参数的参数,特别是在URI锚图中.从属键始终指向地图.

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

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

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

!#页=简介:UNAME,温迪|在线,今天

这是用于基于散列更改来驱动应用程序状态的约定.


Nic*_*zol 8

import/export现在正在使用ES6完成工作._如果我的大部分功能都被导出,我仍然倾向于使用前导而不是导出的函数.

如果只导出一个类(如在角项目中),则根本不需要它.

export class MyOpenClass{

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

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

}

function close(){ /*... this is really private... */ }
Run Code Online (Sandbox Code Playgroud)