逗号运算符的一个令人信服的案例
逗号运算符是类C语言(例如JavaScript和C++)中不太为人所知的运算符之一。本质上,它界定了一系列表达式并仅返回最后一个表达式的结果。
const a = 1; const b = 2; const c = 3; const result = (a, b, c, 4, 5, 6, true); console.log(result); // true
if (false, true) console.log('hello'); // hello
那么很自然地会问:什么时候将多个表达式塞进一行会有用?此外,即使有用,为什么用逗号分隔的表达式序列(在单行)比分号分隔的语句序列(跨多行)更具可读性和可维护性?我们什么时候应该选择其中一种而不是另一种?
这些是我多年来一直努力回答的问题,但现在我想我终于有了答案。在本文中,我针对逗号运算符提出了一个令人信服的案例(坦率地说,也许是唯一的一个案例)。
一个激励人心的例子
我们先来说一下条件三元运算符。如下所示,如果条件为真,则评估值。否则,它评估另一个。这里强调关键字“评估”,因为分支仅在满足条件时执行。
const result = condition ? value : another;
在大多数情况下,它都是整洁漂亮的。然而,当我们需要在返回条件值之前在分支之间执行更复杂的逻辑时,它就会崩溃。此时,我们诉诸这种不幸的变态:
let result; // Uninitialized! Yikes! if (condition) { // Do some complex stuff in between... doSomething(); // ... result = value; // Actual Assignment } else { // Do other complex stuff in between... doAnotherThing(); // ... result = another; // Actual Assignment } // Hopefully we didn't forget to initialize `result`!
现在这个配方存在很多问题。
- 结果一开始是未初始化的。这本质上并不是邪恶的,但避免由于未定义而导致错误的一种简单且经过验证的方法是始终初始化变量。
- 结果的初始化实际上是在分支的底部——与其声明相分离。
- 在条件结束时,我们最好希望结果肯定已初始化。如果不是我们,我们最好希望我们的队友同样执行这一点。如果不是现在,我们最好希望未来的开发者也能坚持这一点!
如果我们坚持使用条件三元表达式,就有办法绕过这个限制。我们只需要将代码重构为函数即可。这绝对是说起来容易做起来难。这个噱头很快就过时了!
function computeWrappedValue() { // ... return value; } function computeWrappedAnother() { // ... return another; } // How cumbersome! const result = condition ? computeWrappedValue() : computeWrappedAnother();
基于表达式的编程语言(例如 Rust)有更优雅的解决方案。通过将 if 语句 重新分类为 if 表达式 ,可以对每个分支进行求值,从而返回稍后可以存储在变量中的值。
// A conditional ternary operator thus looks like this. Each branch // returns a value, which is captured by the `result` variable. // We thus ensure that `result` is always initialized by construction. let result = if condition { value } else { another };
// If we wanted to do something more complex, we use the same syntax. let result = if condition { do_something(); // In Rust, the last expression without a semicolon is the value // that will be "returned" by the overall `if` expression. result } else { do_another_thing(); another };
我们可以用类似 C 的语言来模拟这个吗? 你可能早就预见到了我的发展方向,但是可以!
一个令人信服的案例
我们想要的是一种在返回三元分支内的值之前任意执行语句的方法。好吧,对我们来说幸运的是,这正是逗号运算符的用途。
// Parenthesized for clarity. const result = condition ? (doSomething(), value) // evaluates to `value` : (doAnotherThing(), another); // evaluates to `another`
这个公式的巧妙之处在于,分支表达式仅在必要时才进行计算。我们有效地模拟基于表达式的编程语言的行为。临时包装函数的时代已经一去不复返了!
但是可惜,我们只能用这种技术走这么远。你可以想象,对于一些足够大的 n,将 n 条语句塞进一行已经需要重构到它自己的函数中。就我个人而言,当 n > 时我已经重新考虑了。 3. 就可读性而言,任何高于此值的结构都是可疑的。
// Maybe we should reconsider here? const result = condition ? (x++, thing = hello(), doSomething(), value) : (++y, thing = world(), doAnotherThing(), another);
// Okay, stop. Definitely turn back now! const result = condition ? ( x++, thing = hello(), doSomething(), doMore(y), doEvenMore(thing), value, ) : ( ++y, thing = world(), doAnotherThing(), doMore(y), doEvenMore(thing), another, ); // Unless, of course, you're fine with this. It kinda does // look like a Rust `if` expression if you squint hard enough.
结论
总而言之,我们看到了逗号运算符的一个令人信服的案例:复杂的条件三元运算。当分支又短又甜时,逗号运算符会大放异彩,但在三个内联语句之后很快就会过时。到那时,重构代码可能会更好。
那么你应该使用逗号运算符吗?老实说......是的!可读的代码会考虑到下一个读者,因此只要逗号链不会太长,我就会接受甚至鼓励这种编码风格。如果我们考虑替代方案(即未初始化的变量和重构的微函数),逗号运算符毕竟没那么糟糕。
在实践中,我已经在自己的代码库中添加了这些看起来很有趣的逗号运算符。但公平地说,我很少需要多语句三元条件。但当我这样做时,我的腰带上就有了一个很酷的工具,可以简洁地表达我的意图。
为此,我对逗号运算符提出了令人信服的理由。
以上是逗号运算符的一个令人信服的案例的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。
