【发布时间】:2011-09-26 16:46:42
【问题描述】:
我看到 JavaScript 中某些对象的某些属性以双下划线开头。例如,__defineGetter__ 或 __defineSetter__ 或 __proto__。
它是约定定义的 ECMAScript 规范吗?或者这只是开发者社区的惯例?
【问题讨论】:
标签: javascript double-underscore
我看到 JavaScript 中某些对象的某些属性以双下划线开头。例如,__defineGetter__ 或 __defineSetter__ 或 __proto__。
它是约定定义的 ECMAScript 规范吗?或者这只是开发者社区的惯例?
【问题讨论】:
标签: javascript double-underscore
我相信答案需要更新。这些名称现在是 ECMA-262 的一部分,所以是的,命名约定现在在 ECMAScript 规范中定义。
从 ECMAScript 2015 (ES6) 开始,以下内容已标准化*:
从 ECMAScript 2017 (ES8) 开始,以下内容已标准化*:
__defineGetter__( P, getter )__defineSetter__( P, setter )__lookupGetter__ (P)__lookupSetter__ (P)*:但是应该注意,上面列出的部分都在附件 B“Web 浏览器的附加 ECMAScript 功能”中定义,附件 B 附带的注释为(强调我的)
本附件描述了基于 Web 浏览器的 ECMAScript 实现的各种遗留特性和其他特性。本附件中指定的所有语言特性和行为都有一个或多个不受欢迎的特性,如果没有遗留使用,将从本规范中删除。但是,大量现有的对这些特性的使用网页意味着网络浏览器必须继续支持它们。本附件中的规范定义了这些遗留功能的可互操作实现的要求。
这些功能不被视为核心 ECMAScript 语言的一部分。 程序员在编写新的 ECMAScript 代码时不应使用或假设存在这些特性和行为。 ECMAScript 不鼓励实现这些功能,除非实现是 Web 浏览器的一部分,或者需要运行与 Web 浏览器相同的旧版 ECMAScript 代码。
有效地弃用它们的用法。
【讨论】:
这些是由特定浏览器定义的属性,不是由 ECMAScript 定义的。
因此,name collision 需要避免。如果他们将属性称为defineGetter,则无法保证网站的代码还没有定义同名的属性——这会导致很多问题。但是,附加两个下划线已成为定义浏览器特定属性的事实上的方式(因为某些网站不太可能使用该约定)。
您可能会注意到其他浏览器开始使用与其他浏览器相同的命名约定(例如使用__proto__),但在所有浏览器之间仍然不能普遍保证(例如,IE 没有定义__proto__ property)。
另外:使用两个下划线作为“系统定义的”标识符(与程序员定义的标识符相反)的约定由来已久,所以我不知道该约定是什么时候“开始”的——至少是只要 C++(见http://en.wikipedia.org/wiki/Name_mangling#Simple_example)
【讨论】:
google 对象或 jQuery 对象),然后在该对象范围内定义所有方法/变量。这是为了避免名称冲突的问题。但是,这绝不意味着每个框架都这样做。
Object.prototype 或其他方式。
这样名称冲突的可能性很小。
JavaScript 的全局命名空间存在这个问题,每个人都可以更改或访问任何内容。有一些数据隐藏技术,但有时不起作用。
例如,如果您这样做,您的 jquery 将停止工作:
$ = "somethingElse";
【讨论】: