iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Modern Web

你阿嬤成為網頁前端工程師的第一步系列 第 26

[Day 26] 阿嬤都看得懂的程式語言在幹嘛

阿嬤都看得懂的程式語言在幹嘛

我們都希望能夠有個神燈精靈,能夠實現我們的所有願望。然而,我們的願望最後常常成為猴爪的悲劇。所以英文俗諺才說,「小心許願,因為它可能實現」。今天就讓我們練習怎麼許願吧!

想像我們有個非常厲害,但也非常耿直的神燈精靈。只要我們下的指令,無論多需要嚴密計算,或者多需要無聊重複,它都會盡量完成。然而,神燈精靈只能接受最直接的指令,沒辦法猜測我們的暗示或言外之意。同時,這位神燈精靈的記性也很差,我們沒有特別請它記得的事物,它就不會記得;另外,就算我們有請它記得,在完成當前任務以後,它也會立刻忘記。

那麼,我們要怎麼寫下我們任務,讓神燈精靈能夠順利執行呢?讓我們想想,應該怎麼讓神燈精靈,幫我們用 1000 元紙鈔買杯 40 元的珍珠奶茶呢?

首先,因為我們說過神燈精靈的記性很差,所以它不會記得我們給它多少錢,也不會記得我們要買什麼東西。不過,這個神燈精靈有個好玩的地方:只要我們給事物一個名字,這個神燈精靈就會在執行該次任務的時候,記得那個名字,以及這個名字代表的事物。所以,我們要幫神燈精靈寫下:

有個名字 十月五號的錢錢 = 1000
有個名字 十月五號的待購商品 = {品項:"珍珠奶茶",價錢:40}

我們不能只寫下 1000,不然神燈精靈會忘記這個 1000 是什麼東西。我們必須告訴神燈精靈說,有個名字叫作「十月五號的錢錢」,這個名字代表 1000 這個數字。我們使用1 個半形等號,將這個名字與代表的東西串連起來。當然,你可以不把名字取叫「錢錢」,可以是「貓貓」、「狗狗」,神燈精靈都會記得。由於這個名字可以隨便亂取,也可以代表各種東西,所以我們把這個名字叫作 「變數」(variable)。不過,因為我們這邊的任務和錢有關,為了我們自己閱讀方便,還是就叫「十月五號的錢錢」吧!

我們把告訴神燈精靈有哪些變數的動作,稱作 「宣告」 (declare) 變數。由於我們是使用變數,幫助神燈精靈記得這些事物,這就好像我們把這些事物,存放進神燈精靈的記憶當中一樣;因此,我們會說。我們用這些變數來存入 (save) 這些事物。由於我們會告訴神燈精靈,這些變數代表哪些事物,這就好像我們讓這些變數指到這些事物一樣;因此,我們也會說,我們把這些事物 指定 (assign) 到某個變數。

當我們的變數代表的東西,裡面有很多不同的屬性,例如上面看到的「品項」、「價錢」的時候,我們會把這個東西叫作 「物件」(object)--畢竟每個物件都有很多不同的屬性嘛。我們在告訴神燈精靈,這個東西是個物件的時候,會使用一個花括弧,表示這些屬性都屬於同個物件,當中的屬性則用半形逗號隔開。另外,當我們寫下純文字/文字串 (character/string)的時候,必須前後加上雙引號,才能夠和告訴神燈精靈的名字區分開來。如果是 數字 (number),就單獨出現就可以了,不用加上任何括弧或引號。

然後,我們要告訴神燈精靈怎麼做買東西這件事情:買東西這件事情是這樣的,我會跟你說錢錢是多少,也會告訴你待購商品是什麼。然後你會從待購商品中,找到價錢。把錢錢減掉待購商品的價錢後,回覆我錢錢剩下多少。

讓我們把上面這段文字用神燈精靈語簡寫一下。我們會先跟神燈精靈說,

  1. 它現在有個要去執行的功能 (function,或譯「函式」),但是由於神燈精靈記性很差,不會記得有這功能,所以我們同樣要給一個功能的名字,像這邊可以是「買東西」。然後,
  2. 我們會把神燈精靈在執行「買東西」這個功能時,這個功能會涉及的東西,例如錢錢、待購商品,寫在圓括弧裡。最後,
  3. 我們會把神燈精靈要做的事情,寫在花括弧裡。至於神燈精靈做完事情後,是否需要
  4. 回覆 (return) 什麼資訊,或者是否回復資訊,就看情況而定。另外,
  5. 當我們談到物件的屬性,例如待購商品的價格時,會在物件後面加個半形句點,在半形句點後再加上屬性。因此,我們會寫下:
有個功能 買東西(錢錢, 待購商品){
    有個變數  阿嬤主人要的計算結果 = 錢錢 - 待購商品.價錢;
    回覆  阿嬤主人要的計算結果
}

值得注意的是,在計算錢錢減掉待購商品的價錢後,由於神燈精靈的記性很差,所以它根本不會記得這個計算的結果。這也是為什麼在上面的指示中,我們還是必須先給一個變數,也就是「阿嬤主人要的計算結果」(同理,我們可以取任何變數名稱都行,例如「算算」或者「結果啦」都可以),然後讓這個變數去表示計算的結果,這樣神燈精靈才會有辦法回覆這個結果。

另外,由於神燈精靈的記性真的很差,所以它在做完任何功能以後,因為任務已經結束了,所以它會直接忘記這個功能裡,我們要它記得的事物。在上面的指示中,只要神燈精靈做完買東西這個功能,它就不會記得阿嬤主人的計算結果是什麼東西。因此,當做完買東西*這個功能後,如果我們問神燈精靈,阿嬤主人的計算結果是什麼呢?神燈精靈會完全不知道那是什麼鬼東西喔!

設定好買東西的功能以後,我們只要告訴神燈精靈:我要你執行買東西的功能,對象是十月五號的錢錢十月五號的待購商品,神燈精靈就會回覆我們結果了。用神燈精靈語來簡寫,看起來會像這樣:

買東西(十月五號的錢錢, 十月五號的待購商品)

這時候,神燈精靈就會把十月五號的錢錢,也就是 1000,減掉十月五號的待購商品的價錢,也就是 40,得到 960 以後,用阿嬤主人的計算結果來代表與記得 960 這個結果,並且回覆我們這個阿嬤主人的計算結果,也就是 960。

你會說,只是買個東西也太簡單了吧,不用神燈精靈,阿嬤我每天自己在算帳啊!沒錯,但是如果需要算一百次、一萬次呢?阿嬤應該會覺得很崩潰吧!沒錯,這就是神燈精靈厲害的地方,它可以永不疲倦地執行繁複的計算,而且速度比我們快速,也不會出錯。例如,當我們拿到一張待購商品長達 105 項的清單時,我們會怎麼做呢?

首先,我們會先幫神燈精靈記得這張清單。怎麼記得呢?沒錯,先給這張清單一個名字。給出名字以後,再告訴神燈精靈這張清單中,有哪些待購商品。當然,每個待購商品,都會有品項與價格。在神燈精靈語中,清單是用方括弧來表示,當中的項目用半形逗號隔開。因此,我們會寫下:

有個變數 十月五號的待購商品清單 = [ {品項:"珍珠奶茶",價錢:40}, {品項:"椰果奶茶",價錢:35}, {品項:"珍珠紅茶",價錢:35}, ..., {品項:"椰果紅茶",價錢:25}]

注意,上面的刪節號是礙於篇幅,用來表示沒寫出的 101 項物件,並不是在寫下來的時候就長那樣喔。

接著,我們可以告訴神燈精靈,我們要有一個結餘帳款的功能,這個功能是這樣的:我們待購商品清單中有 105 項物件,然後先對錢錢和清單中第 1 項東西執行買東西的功能,再對錢錢和第 2 項東西執行買東西的功能,再對錢錢和第 3 項東西執行買東西的功能...... 再對錢錢和第某項東西執行買東西的功能,再對錢錢和第某項後那項東西執行買東西的功能 ...... 最後對錢錢和第 105 項東西執行買東西的功能,然後回覆最後錢錢剩下多少。

上面這個做法很直覺,但是卻有個嚴重的問題。我們在最前面已經告訴神燈精靈,錢錢 = 1000,所以,如果我們只是一直對錢錢和清單中的東西執行買東西的功能,最後神燈精靈還是只會記得錢錢 = 1000,所以也就會告訴我們錢錢 = 1000。因此,我們必須在每次對錢錢和清單中的東西執行買東西的功能後,就告訴神燈精靈,現在錢錢不是 1000 了,而是執行完買東西的功能後回覆的結果。換句神燈精靈的話說,我們必須每次都把錢錢 = 買東西(錢錢,清單中第某項東西)。

那麼,我們要怎麼告訴神燈精靈,我們要拿清單中的哪項東西呢?很簡單,我們會在代表清單的變數後加上方括弧,再在方括弧裡面放入數字,來代表那是第幾項。值得注意的是,在神燈精靈的文化中,是用 0 起算最開頭的東西。因此,待購商品清單中第一項東西,用神燈精靈語來說,就會是

待購商品清單[0]

聰明的阿嬤應該可以想到,那麼,在神燈精靈語中,待購商品清單中第四項東西的價錢,我們就會說

待購商品清單[3].價錢

另外還有個嚴重的問題:聰明的阿嬤應該看得出來,我在寫上面這個做法的時候,其實就是不斷複製貼上,實在很不 DRY!所以懶惰聰明的工程師當然會想把重複的部分提取出來。讓我們觀察一下,上面這個做法哪邊重複了呢?其實就是「對錢錢和清單中第 ?? 項東西執行買東西的功能」的地方重複了。那麼,那個 ?? 的部分有沒有什麼規律,我們又可以怎麼描述呢?

我們會發現,那個 ?? 就是從 0 開始跳,下次變 1,再來變 2 ...... 再來變 n,再來變 n+1 ......,最後變 104 就結束。換句話說,我們只要指定好開始是幾,下次是幾,還有最後是幾,就可以告訴神燈精靈該怎麼做這個重複的動作。我們會把開始條件、結束條件、下次跳幾號的條件放入圓括弧中,並且用半形分號隔開。當然,我們說從 0 開始,神燈精靈是記不住的;所以,我們還是必須給一個變數,來存入這個跳號的數字。因此,這個重複的模式會這樣說:

重複做 (有個變數 跳號 = 0; 跳號<105; 跳號 = 跳號 +1)

然後,就像功能的指令一樣,我們會把神燈精靈要做的事情寫進花括弧裡;因此,用神燈精靈語來說,整個結餘帳款的功能看起來會像這樣:

有個功能  結餘帳款(錢錢, 待購商品清單){
	重複做(有個變數 跳號 = 0; 跳號<105; 跳號 = 跳號 +1){
		錢錢 = 買東西(錢錢, 待購商品清單[跳號])
	}
	回覆 錢錢
}

上面的寫法已經很棒了,只有最後一個小小的問題:十月五號的待購商品清單是有 105 項沒錯,可是如果十月六號的清單有 83 項,十月七號有 561 項,那豈非每次都還要重寫一次?沒關係,神燈精靈語裡面,通常可以直接幫我們計算清單的長度。在這邊,我們先把清單的長度當成清單這個東西的一個屬性;因此,清單的長度會寫成:

清單.長度

所以,我們最後可以把結餘帳款的功能改寫成這樣:

有個功能  結餘帳款(錢錢, 待購商品清單){
	重複做(有個變數 跳號 = 0; 跳號<清單.長度; 跳號 = 跳號 +1){
		錢錢 = 買東西(錢錢, 待購商品清單[跳號])
	}
	回覆 錢錢
}

最後,只要我們執行

結餘帳款(十月五號的錢錢, 十月五號的待購商品清單)

就可以得到十月五號的錢錢減掉十月五號的待購商品清單每個東西的價格後,得到的結餘囉!

這個重複做的模式,有個炫炮的名稱,叫作 「迴圈」(loop)

嗯嗯,看來神燈精靈還是挺好用的。不過,就在阿嬤們額手稱慶的時候,突然傳來一個作為阿嬤會很爽,但是作為工程師會很幹的喜訊/ 噩耗:飲料店老闆年中大放送啦!只要價格 > 30 的東西,全部都算 30 就好了!這時候,我們應該怎麼跟神燈精靈說呢?

直覺地,我們應該會說,那就在重複做買東西這個功能的時候,做個判斷就好啦!如果清單中的這項東西的價格 > 30,我們就執行買東西(錢錢, 30);否則,就執行原本的錢錢 = 買東西(錢錢, 待購商品清單[跳號]) 就行了。

沒錯,因此,在這個狀況中,我們會把要做判斷的條件放進圓括弧中,然後把符合條件後要做的事情,放進花括弧中。因此,在這個跳樓大特價的情境下,我們給予神燈精靈的指示看起來會像這樣:

有個功能  結餘帳款(錢錢, 待購商品清單){
	重複做(有個變數 跳號 = 0; 跳號<清單.長度; 跳號 = 跳號 +1){
		如果(待購商品清單[跳號]>30){
			錢錢 = 錢錢 - 30
		} 否則 {
			錢錢 = 買東西(錢錢, 待購商品清單[跳號])
		}
	}
	回覆 錢錢
}

問題來了,我們要判斷大於、小於都不會是問題,那我們要判斷等於怎麼辦呢?因為等於符號已經被我們拿去做變數宣告了啊!!沒關係,一個等於符號不夠,你有用第二個嗎?沒錯,我們判斷是否相等的方式,就是使用** 2 個等於符號**。例如,當我們要判斷某項商品的價格是否等於 30
時,就會寫下:

待購商品清單[跳號]==30

值得注意的是,我們可以當作判斷條件的事情,一定都是我們可以回答「對」(True) 或「錯」 (False) 的。例如,十月五號的待購商品清單中第 0 個品項的價格是 40,那麼,十月五號的待購商品清單中第 0 個品項的價格 > 30 嗎?答案是「對」。十月五號的待購商品清單中最後一個品項的價格是 25,那麼,十月五號的待購商品清單中第 0 個品項的價格 > 30 嗎?答案是「錯」。因此,「待購商品清單[跳號]>30」這件事情,才能夠當作判斷的條件。

這些我們可以回答「對」或「錯」的事情,我們說它們具備真假值,也叫作「布林值」(boolean)。真假值和前面我們提到的東西都不太一樣。前面我們提過數字、提過文字串、提過物件,也提過清單。這些東西的類別,我們稱作「型別」(type)。

根據上述討論,我們可以發現,型別會影響運算的方式。因此,各型別間也有各自的運算方式。當我們學習某個神燈精靈的方言中有哪些型別,我們也會很自然地問說,這個方言中的這些型別又有哪些原生的運算方法。例如,數字的運算方法通常包含加減乘除;文字串的運算方法通常包含字串合併、字串切分、字串搜尋;真假值 / 布林值的運算通常包含而且 (and)非 (not), 以及 或者(or)

在某些神燈精靈語的方言中,型別是很重要的。我們必須告訴神燈精靈,想要它記得的東西是屬於哪個型別,它才有辦法理解。這其實很好理解,畢竟, 1+"Logos" 會等於什麼!? 根本看不懂啊這句話!因此,在那些方言中,除了要告訴神燈精靈有個變數以外,我們還必須直接告訴神燈精靈,那個變數指到的東西是什麼類型。這種方言,我們會說它們是「強型別」。寫起來會像這樣:

數字 錢錢 = 1000

但是,在某些很會腦補的神燈精靈文化中,神燈精靈會自己幫我們做判斷。例如,它看到 1+"Logos" 的時候,會自動腦補說,阿嬤主人應該是想要把 1 當成文字,然後和後面的文字合併再一起吧!所以,它會把 1+"Logos" 這個指令,當成 "1"+"Logos",結果就會回答 "1Logos"。也因此,我們不需要在宣告變數的時候,指定好這個變數的型別。這種方言,我們就說它們是「弱型別」。

弱型別的方言聽起來很美好,但是很多時候,神燈精靈的腦補未必如同我們的想像,也因此會鬧出很多錯誤。因此,在使用弱型別方言的時候,就需要特別注意,在那個文化中,神燈精靈會怎麼理解不同型別的轉換,以免神燈精靈做出意料之外的行為喔!

最後,讓我們總結以上 4 個神燈精靈語的特徵:

  1. 在我們希望神燈精靈記得我們告訴他的新事物時,必須使用名稱,也就是變數,來進行儲存。
  2. 這些變數中儲存的東西,會分成不同的類型,也就是型別;這是為了要讓神燈精靈知道怎麼計算或處理這些東西。
  3. 我們可以讓神燈精靈替我們執行不會出錯的條件判斷
  4. 我們可以讓神燈精靈替我們執行重複繁瑣的迴圈

電腦就像我們的神燈精靈,而程式語言就是我們和電腦溝通的方式。無論我們學習怎麼樣的程式語言,我們都可以看看這 4 個特徵,在這個程式語言中會怎麼表達。那麼,接下來,我們就要開始學習 JavaScript 這個程式語言了!


上一篇
[Day 25] 阿嬤都看得懂的 CSS 微互動元件
下一篇
[Day 27] 阿嬤都看得懂的 JavaScript 怎麼寫
系列文
你阿嬤成為網頁前端工程師的第一步30

尚未有邦友留言

立即登入留言