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 中下划线前缀的重要性。
Is the underscore prefix in JavaScript only a convention, like for example in Python private class methods are?
From the 2.7 Python documentation:
“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).
Does this also apply to JavaScript?
Take for example this JavaScript code:
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.
发布评论
评论(6)
这只是一个约定。 Javascript 语言不会为以下划线字符开头的标识符赋予任何特殊含义。
也就是说,对于不支持封装的语言来说,这是一个非常有用的约定a> 开箱即用。尽管没有办法阻止某人滥用您的类的实现,但至少它确实阐明了您的意图,并首先记录了此类行为错误。
That's only a convention. The Javascript language does not give any special meaning to identifiers starting with underscore characters.
That said, it's quite a useful convention for a language that doesn't support encapsulation out 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 wrong in the first place.
JavaScript 实际上确实支持封装,通过一种涉及在闭包中隐藏成员 (Crockford) 的方法。也就是说,它有时很麻烦,并且下划线约定是一个非常好的约定,可用于私有的内容,但您实际上不需要隐藏它们。
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 need to hide.
欢迎来到 2019 年!
似乎有一个扩展类语法以允许
#
前缀变量为私有已被接受。 Chrome 74 附带提供此支持。按照惯例,带有
_
前缀的变量名称被视为私有,但仍然是公共的。请参阅 https://caniuse.com/#feat=mdn-javascript_classes_private_class_fields
Welcome to 2019!
It appears a proposal to extend class syntax to allow for
#
prefixed variable to be private was accepted. Chrome 74 ships with this support._
prefixed variable names are considered private by convention but are still public.See https://caniuse.com/#feat=mdn-javascript_classes_private_class_fields
JSDoc 3 允许您使用
@access private
(以前的@private
标记)来注释您的函数,这对于向其他开发人员广播您的意图也很有用 - http://usejsdoc.org/tags-access.htmlJSDoc 3 allows you to annotate your functions with the
@access private
(previously the@private
tag) which is also useful for broadcasting your intent to other developers - http://usejsdoc.org/tags-access.html除了隐私约定之外,我还想帮助人们认识到下划线前缀也用于依赖于独立参数的参数,特别是在 URI 锚映射中。从属键始终指向映射。
示例(来自 https://github.com/mmikowski/urianchor ):
浏览器上的 URI 锚点搜索字段更改为:
这是用于根据哈希更改驱动应用程序状态的约定。
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.
Example ( from https://github.com/mmikowski/urianchor ) :
The URI anchor on the browser search field is changed to:
This is a convention used to drive an application state based on hash changes.
import/export
现在使用 ES6 来完成这项工作。如果我的大部分函数都是导出的,我仍然倾向于在未导出的函数前加上_
前缀。如果您仅导出一个类(例如在角度项目中),则根本不需要它。
import/export
is now doing the job with ES6. I still tend to prefix not exported functions with_
if most of my functions are exported.If you export only a class (like in angular projects), it's not needed at all.