var和let的语义
Var和let是对机器和其他程序员的声明:
我希望这个赋值在执行过程中发生变化。不要依赖于这个赋值的最终值。
使用var和let的含义
Var,并强制其他程序员读取从声明到最终使用的所有中间代码,并在程序执行时推断赋值的值。
它们削弱了ESLint和其他语言服务的机器推理,从而在以后的赋值中正确检测输入错误的变量名,并在内部作用域忘记声明的情况下对外部作用域变量名进行作用域重用。
它们还导致运行时在所有代码路径上运行多次迭代,以检测它们实际上是常量,然后才能优化它们。尽管这比错误检测和开发人员可理解性的问题要小。
何时使用const
如果引用的值在执行过程中没有改变,那么表达程序员意图的正确语法是const。对于对象,改变引用的值意味着指向另一个对象,因为引用是不可变的,而对象不是。
“常量”对象
对于对象引用,指针不能更改为另一个对象,但创建并赋值给const声明的对象是可变的。可以从const引用的数组中添加或删除项,也可以更改const引用对象的属性键。
为了实现不可变对象(同样,这使你的代码更容易为人类和机器推理),你可以object .freeze对象在声明/赋值/创建,像这样:
const Options = Object.freeze(['YES', 'NO'])
freeze确实对性能有影响,但您的代码可能因为其他原因而变慢。你想要侧写它。
你也可以将可变对象封装在状态机中,并返回深度副本作为值(这就是Redux和React状态的工作方式)。有关如何从第一原则构建全局状态的示例,请参见避免在Browser JS中使用可变全局状态。
当var和let是一个很好的匹配
Let和var表示可变状态。在我看来,它们应该只用于建模实际的可变状态。比如“连接是否存在?”
这些最好封装在可测试的状态机中,这些状态机公开了表示“连接的当前状态”(在任何时间点都是常数)的常量值,以及代码的其余部分真正感兴趣的内容。
加上合成副作用和转换数据,编程已经够难了。通过创建带有变量的可变状态将每个函数变成不可测试的状态机只会增加复杂性。
要了解更细致的解释,请参见Shun the Mutant - const的案例。