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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4484424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:36:40  来源:igfitidea点击:

Underscore prefix for property and method names in JavaScript

javascriptscopenaming-conventions

提问by Kenny Meyer

Is the underscore prefix in JavaScript only a convention, like for example in Python private class methods are?

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

From the 2.7 Python documentation:

来自 2.7 Python 文档:

“Private” instance variables that cannot be accessed except from inside an object don't exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member).

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

Does this also apply to JavaScript?

这也适用于 JavaScript 吗?

Take for example this JavaScript code:

以这段 JavaScript 代码为例:

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

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

Also, underscore prefixed variables are used.

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

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

Only conventions? Or is there more behind the underscore prefix?

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



I admit my question is quite similar to this question, but it didn't make one smarter about the significance of the underscore prefix in JavaScript.

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

采纳答案by Karuhanga

Welcome to 2019!

欢迎来到 2019 年!

It appears a proposalto extend class syntax to allow for #prefixed variable to be private was accepted. Chrome 74 shipswith this support.

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

_prefixed variable names are considered private by convention but are still public.

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

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.

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

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

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

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

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

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

回答by Frédéric Hamidi

That's only a convention. The Javascript language does not give any special meaning to identifiers starting with underscore characters.

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

That said, it's quite a useful convention for a language that doesn't support encapsulationout of the box. Although there is no way to prevent someone from abusing your classes' implementations, at least it does clarify your intent, and documents such behavior as being wrongin the first place.

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

回答by Zach

JavaScript actually does support encapsulation, through a method that involves hiding members in closures(Crockford). That said, it's sometimes cumbersome, and the underscore convention is a pretty good convention to use for things that are sort of private, but that you don't actually needto hide.

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

回答by philrabin

JSDoc 3 allows you to annotate your functions with the @access private(previously the @privatetag) which is also useful for broadcasting your intent to other developers - http://usejsdoc.org/tags-access.html

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

回答by Sam Araiza

"Only conventions? Or is there more behind the underscore prefix?"

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

Apart from privacy conventions, I also wanted to help bring awareness that the underscore prefix is also used for arguments that are dependent on independent arguments, specifically in URI anchor maps. Dependent keys always point to a map.

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

Example ( from https://github.com/mmikowski/urianchor) :

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

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

The URI anchor on the browser search field is changed to:

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

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

This is a convention used to drive an application state based on hash changes.

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

回答by Nicolas Zozol

import/exportis now doing the job with ES6. I still tend to prefix not exported functions with _if most of my functions are exported.

import/export现在正在使用 ES6 完成这项工作。_如果我的大部分函数都被导出,我仍然倾向于在未导出的函数前加上前缀。

If you export only a class (like in angular projects), it's not needed at all.

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

export class MyOpenClass{

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

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

}

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