为什么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#nodeType
和XMLHttpRequest#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