为什么Node.js中的事件不是常量?

我是新来的节点,但我来自广泛的编程背景。 我看到的每一个地方(无论是在教程还是在我看到的产品代码中),人们绝大多数使用硬编码的string而不是常量来识别事件。

我从npm 最依赖于软件包列表中select了一个随机的例子来说明我的意思: “请求”库 – 为什么他们每次都inputstring'data'来发出和使用 «data»事件,而不是定义图书馆的常量?

在我意识到的任何编程语言中,使用常量都被认为是一个好习惯,然而节点开发人员似乎完全满足于硬编码的方法。 为什么?

由于JavaScript的dynamic特性,因此它不适用于Node.js。

假设一个模块定义了一个常量data 。 那么就需要将其导出,作为其事件驱动API的一部分。 诸如:

 const data = 'data'; class Api extends EventEmitter () { constructor () { setTimeout(() => { this.emit(data); }, 2 * 1000); } } module.exports = { data, Api }; 

那么,从外面我们会有这样的东西:

 const foo = require('./foo'); const { Api, data } = foo; const api = new Api(); api.on(data, () => { // ... }); 

基本上,这样的事情。 那么如果你在开始时输错了data呢? 如果不是

 const { Api, data } = foo; 

您错误地input了:

 const { Api, Data } = foo; 

这将工作,没有任何错误。 Data只是undefined 。 当您尝试访问不存在的对象属性时,您不会收到错误,您只需返回undefined

所以,你不会得到一个编译器错误,但是现在你正在发送数据,但是你正在监听的是undefined 。 常数没有任何帮助,你仍然要确保你不要输错它的名字。

这不会比使用string更好或更差,因为你不允许input任何内容。

因此,长话短说,常数不会改善情况,只会导致更多的打字,使事情变得更加复杂 – 但是并不能解决任何实际问题。

简而言之,string是JavaScript可用的最佳常量。 将它们隐藏在一些静态库variables的后面不会使开发人员的代码变得更加简洁,可读(我的观点)或performance性; 这就是为什么它从来没有成为stream行的惯例。


脆弱性

你的问题似乎意味着硬编码的string在某种程度上比使用variables常量更“脆弱”。 然而,我认为只有当“常数”会随着时间的推移而变化时,才会出现这种情况,对于任何事件types来说都不是这样,因为Node.js库(和浏览器API)也努力保持某种程度的向后兼容发行版。 而且,有些人输错variables的可能性与使用硬编码string时相同,因为JavaScript没有编译时检查属性是否存在或其他。 没有任何保证。


额外上下文

您可能已经注意到,JavaScript缺less一个枚举types,这在很多方面都令人讨厌。

较早的API使用整数值来填充语言中的void ,类似于人们用Java来完成的方式。 例如, Node#nodeTypeXMLHttpRequest#readyState都是这样devise的:

 var node = document.createTextNode('') console.log(node.nodeType) //=> 3 console.log(node.nodeType === Node.TEXT_NODE) //=> true var xhr = new XMLHttpRequest() console.log(xhr.readyState) //=> 0 console.log(xhr.readyState === XMLHttpRequest.UNSENT) //=> true