我看到JavaScript中某些对象的某些属性以双下划线开头。例如,__defineGetter__
或__defineSetter__
或__proto__
之类的内容。
它是一个常规定义的ECMAScript规范吗?或者它可能只是开发人员社区的惯例?
答案 0 :(得分:30)
这些属性由特定浏览器定义,而未由ECMAScript定义。
因此,需要避免name collision。如果他们调用了属性defineGetter
,那么就不能保证网站的代码没有用同一名称定义属性 - 这会导致许多问题。但是,附加两个下划线已经成为定义浏览器特定属性的实际方法(因为某些网站使用该约定的可能性要小得多)。
您可能会注意到其他浏览器开始使用与其他浏览器相同的命名约定(例如使用__proto__
),但在所有浏览器之间仍然没有普遍保证(例如,IE未定义__proto__ property
)
另外:使用两个下划线表示“系统定义”标识符(而不是程序员定义的标识符)的惯例可以追溯很长一段时间,因此我不知道该约定何时“开始” - 至少作为只要C ++(见http://en.wikipedia.org/wiki/Name_mangling#Simple_example)
答案 1 :(得分:5)
这样就不会发生名称冲突。
JavaScript在全局命名空间中存在这个问题,每个人都可以更改或访问任何内容。有一些数据隐藏技术,但有时不起作用。
例如,如果你这样做,你的jquery将停止工作:
$ = "somethingElse";
答案 2 :(得分:1)
我相信答案需要更新。这些名称现在是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代码时不应使用或假定这些功能和行为的存在。除非实现是Web浏览器的一部分或需要运行与Web浏览器遇到的相同的旧ECMAScript代码,否则不建议ECMAScript 实现不实现这些功能。
有效弃用它们。