自從宣告 IE 封印解除,我一改過去儘量用古老寫法以免惹 IE 生氣的保守心態,積極學習現代 JavaScript。猶如鄉巴佬進城,連看見自動販賣機也會大讚科技好進步。對專業前端開發人員來說,2022 年還在介紹這種基本常識簡直笑死,但心想「總有比我更晚解封的人」,還是拋開羞恥心(謎:不要提那種你沒有的東西)分享一下好了。

在一個實際案例學到兩則 JavaScirpt 小技巧,用以下範例展示。它是個用 Vue.js MVVM 做的清單檢視連動介面,點左邊列表項目,右方會出現該筆詳細資訊:

一開始是用我習慣的傳統寫法:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="//unpkg.com/vue@3"></script>
        <style>
            html,body { height: 100%; margin: 0; padding: 0; }
            #app { display: flex; height: 100%; background-color: rgb(105, 109, 109); }
            #app > * { margin: 6px; background-color: white; }
            .list { width: 130px; padding: 6px; border: 1px solid gray; }
            .list div:hover { background-color: #ddd; cursor: pointer; }
            .view { flex-grow: 1; }
            table { margin: 3px; width: 250px; }
            td { padding: 3px; background-color: #eee; }
            td:first-child { width: 80px; text-align: right; background-color: #ddd; }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="list">
                <div v-for="p in players" @click="currPlayer=p">
                    {{p.name}}
                </div>
            </div>
            <div class="view">
                <table>
                    <tr><td>Id</td><td>{{currPlayer && currPlayer.id}}</td></tr>
                    <tr><td>Name</td><td>{{currPlayer && currPlayer.name}}</td></tr>
                    <tr><td>Score</td><td>{{currPlayer && currPlayer.score}}</td></tr>
                </table>
            </div>
        </div>
        <script>
            function player(id, name, score) {
                this.id = id;
                this.name = name;
                this.score = score;
            }
            var players = [
                new player('P01', 'Jeffrey', 32767),
                new player('P02', 'darkthread', 65535),
                new player('P03', '0x270f', 9999),
            ];
            var vm = Vue.createApp({
                data() {
                    return {
                        players: players,
                        currPlayer: null
                    }
                }
            }).mount('#app');
        </script>
    </body>
</html>

寫完不免犯嘀咕,用 C# 寫根本不用這麼麻煩,像是 currPlayer && currPlayer.id 可以寫成 currPlayer?.id (C# 術語:Null-Conditional Operator)、 在 C# 可寫成 new (術語:Projection Initializer)。

好奇心起,查了一下發現在 JavaScript 早就支援同樣的簡潔寫法。

?. 運算子在 JavaScript 叫 Optional Chaining,除了物件屬性,也能用在陣列跟方法上: (瀏覽器支援:Chrom 80+、Firefox 74+,Node.js 14+)

obj?.prop  
obj?.[expr]  
arr?.[index]  
func?.(args)

至於宣告物件時以變數名當屬性名稱 (Shorthand Property Name)的寫法是從 ES2015(ES6) 開始支援的。

            <div class="view">
                <table>
                    <tr><td>Id</td><td>{{currPlayer?.id}}</td></tr>
                    <tr><td>Name</td><td>{{currPlayer?.name}}</td></tr>
                    <tr><td>Score</td><td>{{currPlayer?.score}}</td></tr>
                </table>
            </div>
        </div>
        <script>
            //...略...
            var vm = Vue.createApp({
                data() {
                    return {
                        players, //若要沿用變數名,不用寫成 players: players
                        currPlayer: null
                    }
                }
            }).mount('#app');
        </script>

鄉巴佬進化中。

Tips of using optional chaining (?.) and shorthand prop name { varName } in JavaScript.


Comments

Be the first to post a comment

Post a comment