在Javascript中,这个下划线代表什么意思?

93
var Gallery = Backbone.Controller.extend({
    _index: null,
    _photos: null,
    _album :null,
    _subalbums:null,
    _subphotos:null,
    _data:null,
    _photosview:null,
    _currentsub:null,
    routes: {
        "": "index",
        "subalbum/:id": "subindex",
        "subalbum/:id/" : "directphoto",
        "subalbum/:id/:num" : "hashphoto"
    },
    initialize: function(options) {
        var ws = this;
        if (this._index === null){
            $.ajax({
                url: 'data/album1.json',
                dataType: 'json',
                data: {},
                success: function(data) {
                    ws._data = data;
                    ws._photos =
                    new PhotoCollection(data);
                    ws._index =
                    new IndexView({model: ws._photos});
                    Backbone.history.loadUrl();
                }
            });
            return this;
        }
        return this;
    },
    //Handle rendering the initial view for the
    //application
    index: function() {
        this._index.render();
    },

我正在阅读一个有关backbone.js的教程: http://addyosmani.com/blog/building-spas-jquerys-best-friends/

这些下划线是什么?(_index、_photos、_album) 为什么要使用它们?


2
下划线在语法上没有意义,这可能是某个程序员惯用的约定,用于表示变量的类型。 - Nate Koppenhaver
可能是JavaScript中属性和方法名称的下划线前缀的重复问题。 - BuZZ-dEE
7个回答

178

它意味着私有字段或私有方法。这些方法仅供内部使用。

它们不应在类外调用。

私有字段包含供内部使用的数据。

它们不应该从类外(直接)读取或写入。

注意:非常重要的一点是,仅仅为变量添加下划线并不会使其成为私有变量,这只是一种命名约定。


5
至少,私有字段的概念是存在的,但它们并不真正私有,你可以随意访问它们。上述代码的作者只是希望它们是私有的。仅此而已。 - Sander
太棒了,不知道为什么我花了这么长时间才查找这个!谢谢。 - droid-zilla

22
据我所知,它通常用于表示私有变量(但实际上并没有提供任何隐私,只是一种惯例)。
这个链接简要地讨论了它,尽管他们不建议使用: http://javascript.crockford.com/code.html

3
我喜欢这个链接: “避免那些显示出无能的传统做法。” - Arek
我在调试时使用它们作为快捷方式,特别是在处理 Promises 和其他异步操作时。例如,访问对象的某个属性的“官方”方式可能是 myObj.getSmePromise().then( function(o) { do stuff } ); 但在 Chrome 控制台中输入这个命令很麻烦,所以我设置了 myObj._someValue,理解为“正确的代码”实际上不会访问它 - 然而,这是有幸运的是我的同事也知道这个约定,如果你正在编写下一个 jQuery/lodash/angular/react 或其他框架,我不会指望所有用户都知道或尊重这一点! - FredL

8
当使用_varname时,它只是变量名称的一部分,没有JavaScript的含义。开发人员使用它来表示变量的含义或作用域。在这种情况下,它似乎在告诉开发人员这个变量应该是局部或私有变量。
需要注意的是,在这个特定的例子中,使用_.varname会表示带有underscore.js库的变量或函数。另外,一个人也可以使用_varname来表示包含underscore对象的变量,同样地,在我们的办公室,我们使用$varname来表示包含Jquery对象的变量。

4

这可能用于标记内部/私有属性。就像在Python中,使用下划线前缀变量是一种简单的方式,告诉开发人员变量是内部的,并且最好不要篡改它(如果他们这样做,甚至涉及库的微小更新也可能导致问题)。


2
通常情况下,_ 被用来告诉用户/程序员这是一个私有/受保护的变量。

0
这是一个小补充。如已回答,这些是伪私有变量。但是可以编写伪公共函数来访问这些私有变量。
我被同事的代码搞糊涂了,实际上它具有这个功能(但深藏在一个单独的库中):
class x { 
  constructor(id) {this._id = id} 
  get id() {return this._id}
}
let y = new x(3)

现在你已经拥有了可以正常工作并返回相同值的y.idy._id。但是,如果你执行console.log(y),它只会显示_id键。该键是唯一被打印出来的。

enter image description here


-2
如上所述,这是许多开发人员的一种惯例,但这是一种不好的习惯。如果您在编程方法中必须采用这样的约定,则应该在尝试使用语言之前学习语言、方法和模式。如果有人无法在没有使用“下划线”的情况下区分代码中的公共/私有方法,则您的文档技能极其缺乏。网络上的许多公共项目都非常缺乏文档,这可能就是为什么“下划线”约定被大多数未受过教育的开发人员“接受”,而其他人则决定跟随潮流而不是保持正式的设计模式和方法。这就是为什么“下划线”没有被写入ES6/7版本的原因。
最近我在一篇博客中遇到了一位软件工程经理,他说:“下划线命名约定使得很容易一眼看出变量函数是否打算公开或私有。”我的回答是:“注释就像图片,在这种情况下,它们价值千金。”
有一个免费的文档工具叫做Doxygen。虽然它不特别支持JavaScript,但当您在注释中使用Doxygen前缀时,它可以为您的JavaScript应用程序生成专业文档。当您在代码注释中稍微努力一下时,就可以为开发人员和用户创建具有文档的JavaScript应用程序。

记住,有一些工具可以删除注释和“生产发布”中的控制台语句。 话虽如此,使用源映射也是浪费时间和资源。 在准备好发布之前不要缩小文件大小。即开发构建(不缩小文件大小,保留注释和控制台语句),发布构建(删除注释和控制台语句并缩小开发构建。当其为发布质量代码时,无需重新编译开发构建,只需准备好发布并部署即可)。


3
除非您查看函数的源代码,否则您不会看到评论。 如果您正在使用其他人的库/代码,则能够在不阅读源代码或文档的情况下了解方法的意图会增加一些价值。 在我看来,下划线前缀表示它是不应被依赖的非公共API。 - Isaac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接