逗號運算子的一個令人信服的案例
逗號運算子是類別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的開發環境包括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在後端開發中發揮作用,支持全棧開發。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。
