49

我看到 JavaScript 中某些对象的某些属性以双下划线开头。例如,类似__defineGetter__or__defineSetter__或的东西__proto__。它是约定定义的 ECMAScript 规范吗?或者这只是开发者社区的惯例?

4

3 回答 3

37

这些是由特定浏览器定义的属性,而不是由 ECMAScript 定义的

因此,需要避免名称冲突。如果他们调用该属性defineGetter,则无法保证该网站的代码尚未定义同名的属性——这会导致很多问题。但是,附加两个下划线已成为定义浏览器特定属性的事实上的方式(因为某些网站不太可能使用该约定)。

您可能会注意到其他浏览器开始使用与其他浏览器相同的命名约定(例如 using __proto__),但在所有浏览器之间仍然不能普遍保证(例如,IE 没有定义__proto__ property)。

另外:对“系统定义”标识符(与程序员定义的标识符相反)使用两个下划线的约定可以追溯到很长时间,所以我不知道该约定是什么时候“开始”的——至少和 C++ 一样长(见http://en.wikipedia.org/wiki/Name_mangling#Simple_example

于 2011-07-01T11:25:35.757 回答
7

这样名字冲突就不太可能发生了。

JavaScript 的全局命名空间存在这个问题,每个人都可以更改或访问任何东西。有一些数据隐藏技术,但有时不起作用。

例如,如果您这样做,您的 jquery 将停止工作:

$ = "somethingElse";
于 2011-07-01T11:24:44.733 回答
3

我相信答案需要更新。这些名称现在是 ECMA-262 的一部分,所以是的,命名约定现在在 ECMAScript 规范中定义

从 ECMAScript 2015 (ES6) 开始,以下内容已标准化*:

从 ECMAScript 2017 (ES8) 开始,以下内容已标准化*:

*:但是应该注意,上面列出的部分都在附件 B“Web 浏览器的附加 ECMAScript 功能”中定义,附件 B 随附的注释为(强调我的)

本附件描述了基于 Web 浏览器的 ECMAScript 实现的各种遗留特性和其他特性。本附件中规定的所有语言特性和行为都有一个或多个不受欢迎的特性,如果没有遗留使用,将从本规范中删除。然而,大量现有网页对这些功能的使用意味着网络浏览器必须继续支持它们。本附件中的规范定义了对这些遗留功能的互操作实现的要求。

这些功能不被视为核心 ECMAScript 语言的一部分。程序员在编写新的 ECMAScript 代码时不应使用或假设存在这些特性和行为。不鼓励ECMAScript实现实现这些功能,除非该实现是 Web 浏览器的一部分,或者需要运行 Web 浏览器遇到的相同的遗留 ECMAScript 代码。

有效地弃用它们的使用。

于 2020-03-13T03:35:48.657 回答