# Eloquent JavaScript 3rd edition (2018) 第二章 Program (最後練習題看不懂) --- tags: Javascript relate --- ###### tags: `Javascript` > And my heart glows bright red under my filmy, translucent skin and they have to administer 10cc of JavaScript to get me to come back. (I respond well to toxins in the blood.) Man, that stuff will kick the peaches right out your gills! > > _why, Why's (Poignant) Guide to Ruby # Expressions and statements「表達式」及「陳述式」 一段代碼且會產生一個value叫做expression > A fragment of code that produces a value is called an expression. 如果一個expression回應了一個分段的句子那麼js statement則回應一整個sentence,然而程式就是一個statement的清單列表 > If an expression corresponds to a sentence fragment, a JavaScript statement corresponds to a full sentence. A program is a list of statements. The simplest kind of statement is an expression with a semicolon after it. This is a program: 最簡單的程式就是一個expression後面加個 ";"。 ```javascript= 1; !false; ``` 文中建議最後所有的js程式的一段的後方要加入";" 否則會跟下一行程式混在一起。 陳述式statement:會執行一些程式碼,可能是幾個單詞或是一個片段(但不會是單一個字母),但最大的特徵是不會回傳結果。 表達式expression:最大的特徵在於會回傳結果。 --- # Bindings 為了留住value,js提供了一個東西叫做binding或是variable > To catch and hold values, JavaScript provides a thing called a binding, or variable ```javascript= let caught(這個就是binding) = 5 * 5; ``` 這邊的關鍵字出來了,"let",它可以讓變數(binding)定義這個sentence, The special word (keyword) let indicates that this sentence is going to define a binding. 例子如下: ```javascript= let ten(binding) = 10; console.log(ten * ten); // → 100 ``` let 的變數的value可以被 = 這個operator重新定義 ``` javascript= let mood = "light"; console.log(mood); // → light mood = "dark"; console.log(mood); // → dark ``` 可以把Binding想像成觸手而不是箱子,他們並不是裝著value,而是抓著value 並且兩個bindings可以使用同樣一個value。 一個單一的let 可以指定多個bindings而他們必須被","區隔開來 ```javascript= let one = 1, two = 2; console.log(one + two); // → 3 ``` 同樣的 var 以及 const 同樣可以用來 做跟let一樣的功能: ```javascript= var name = "Ayda"; const greeting = "Hello "; console.log(greeting + name); // → Hello Ayda ``` 不過var目前比較少用容易造成混淆。 The word const stands for constant. It defines a constant binding 這邊代表const只會有一個binding --- ## Binding names > Binding names can be any word. * 隨便你取名啦!! * 不可以用數字開頭 * 符號的部分只可以接受底線(_) 跟錢錢($) 其他符號都不接受 * 還有一些功能字不能使用比方說: ```javascript= break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import interface in instanceof let new package private protected public return static super switch this throw true try typeof var void while with yield ``` 也不太需要去記,你用錯了也會跳出syntax error出來。 ## The environment 簡單來說一個使用各種bindings跟它們的valure作用的地方就是environment > The collection of bindings and their values that exist at a given time is called the environment. 這邊舉例說明像是網頁裡面的funcitons跟網頁載入的以及互動來讀取鍵盤滑鼠的輸入 > For example, in a browser, there are functions to interact with the currently loaded website and to read mouse and keyboard input ## Functions 在環境中很多的value使用的type都是function > A function is a piece of program wrapped in a value > For example, in a browser environment, the binding "prompt" holds a function that shows a little dialog box asking for user input. It is used like this: ![](https://i.imgur.com/NEc4dHh.png) 執行一個function可以被稱作 invoking, calling, applying > Values given to functions are called arguments. arguments是一個value被給予funciton ## The console.log function 在網頁裡面console.log的工具在Developer Tools 如果使用mac command-option-I是它的快捷鍵。 console.log有個特別的地方它含有(.)這個特殊符號在裡面,因為它不是一個簡單的binding,它其實是console這個bindinf在檢索log這個property,更詳細的內容在第四章。 ## Return values 當function產生一個value就可以說它是在做return value > When a function produces a value, it is said to return that value ## Control flow(流程控制) 當程式超過一個statement的時候,statement的程序處理會像說故事一樣從頭到尾的順序走下去 就像這張簡單的示意圖一樣 ![](https://i.imgur.com/fTQ3ntD.png) ### Conditional execution 不過很多時候我們需要它們看情況走一些分枝 ![](https://i.imgur.com/zVWl2iR.png) > Conditional execution is created with the "if" keyword in JavaScript. Conditional execution 常常會使用"if"這個關鍵字來操作: 如果輸入內容是number則跑這個程式 這邊我的內容輸入10,然而如果我輸入字串如"你好"就不會有任何結果產生 ```javascript= let theNumber = Number(prompt("Pick a number")); 2 if (!Number.isNaN(theNumber)) { 3 console.log("Your number is the square root of " + 4 theNumber * theNumber); 5 } Your number is the square root of 100 ``` 所以當你使用if這個關鍵字的時候只有符合條件的時候才會走程序不然的話會走另一條路,這樣的情況就稱作Conditional execution 這邊作者推薦盡量都使用({})去包裹句子除非一些單行的句子可以不使用外其他一律都要用 ```javascript= if (1 + 1 == 2) console.log("It's true"); // → It's true ``` 下面使用了else來創造if之外的另一條路: ```javascript= let theNumber = Number(prompt("Pick a number")); 2 if (!Number.isNaN(theNumber)) { 3 console.log("Your number is the square root of " + 4 theNumber * theNumber); 5 } else { 6 console.log("Hey. Why didn't you give me a number?"); 7 } Hey. Why didn't you give me a number? ``` 這邊可以chian串接更多的路徑使用 else if 它的路徑是意圖又更複雜了 ![](https://i.imgur.com/wvSyFjt.png) ```javascript= let num = Number(prompt("Pick a number")); if (num < 10) { console.log("Small"); } else if (num < 100) { console.log("Medium"); } else { console.log("Large"); } ``` ### while and do loops #### loop 跑一段程式碼很多次,這樣的流程控制就叫做Loop > What we need is a way to run a piece of code multiple times. This form of control flow is called a loop. ```javascript= let number = 0; while (number <= 12) { console.log(number); number = number + 2; } // → 0 // → 2 // … etcetera 這邊就一直重複回到迴圈裡從0開始進去後變成2再去進去變成又回去變成6以此類推 ----------------------------------- 0 2 4 6 8 10 12 ``` 要使用迴圈Loop就得使用"while" 從while裡面的statement得知counter得數10次因此可以得到結果2的十次方 counter 0 進去得出result 2 counter 1 進去得出result 4 counter 2 進去得出result 8 . . . . counter 9 進去得出result ```javascript= let result = 1; let counter = 0; while (counter < 10) { result = result * 2; counter = counter + 1; } console.log(result); // → 1024 ``` #### do do跟while很像但是差別在於一個地方: do loop 至少會執行結果一次才會停下來。 > A do loop is a control structure similar to a while loop. It differs only on one point: a do loop always executes its body at least once, and it starts testing whether it should stop only after that first execution. 像這段程式碼它會持續執行視窗,直到你填入string後才會停止跳出並跑出結果。 ```javascript= let yourName; do { yourName = prompt("Who are you?"); } while (!yourName); console.log(yourName); ``` while vs do...while 兩者的差異在於 while 是先測後跑,而 do...while 是先跑後測。 ## Indenting Code(程式縮排) 下方程式碼兩個都是可行的,這邊想要表示的是這樣的縮進只要所有的程式碼都是使用相同的話,兩隔四四格或是使用tab件都是可以的只要統一就好。 ```javascript= if (false != true) { console.log("That makes sense."); if (1 < 2) { console.log("No surprise there."); } } ``` ## for loops 因為while的pattern太常見了因此提供了一個簡略的方式就是"for" 下方兩個程式碼是輸出一樣的東西: * 第一個分號之前initializes整個loop,同時定義binding * 第二個部分check整個loop要不要繼續跑 * 最後一個部分更新整個loop狀態在每一次迴圈結束之後 ```javascript for (let number = 0; number <= 12; number = number + 2) { console.log(number); } // → 0 // → 2 // … etcetera ``` ```javascript= console.log(0); console.log(2); console.log(4); console.log(6); console.log(8); console.log(10); console.log(12); ``` 下方的程式碼是跑剛剛呈現的2的10次方: ```javascript= let result = 1; for (let counter = 0; counter < 10; counter = counter + 1) { result = result * 2; } console.log(result); // → 1024 ``` ## Breaking Out of a Loop 一種讓loop停下來的方法除了條件完成之外那就是這個"break"了, 下方的程式碼並沒有設定更新迴圈的方式換句話說它會一直跑下去就會產生一種infinite loop就跟當機差不多會一直跑下去,這時候加入break就可以讓他跳出loop並產生一個value出來。 ```javascript= for (let current = 20; ; current = current + 1) { if (current % 7 == 0) { console.log(current); break; } } // → 21 ``` ## Updating bindings succinctly (簡潔的更新bindings) 介紹一些bindings縮寫 ```javascript= counter = counter + 1; counter += 1; counter++ ``` ## Dispatching on a value with switch 利用條件選擇製造的開關,下面的例子是當天氣狀況呈現不同時會有不同的回應出現: 你打入rainy的話會出現Remember to bring an umbrella. 你打入sunny的話會出現Dress lightly. 你打入cloudy 則會出現Go outside. 如果你打的東西無法辨識的話則會跳出 Unknown weather type! 記得要加入break不然就會持續把下方的程式跑完! ```javascript= switch (prompt("What is the weather like?")) { case "rainy": console.log("Remember to bring an umbrella."); break; case "sunny": console.log("Dress lightly."); case "cloudy": console.log("Go outside."); break; default: console.log("Unknown weather type!"); break; } ``` ## Capitalization 以下是一些可以選用的binding命元原則: 不過一般推薦使用第三個 fuzzylittleturtle fuzzy_little_turtle 3333 FuzzyLittleTurtle 333 fuzzyLittleTurtle ## Comments 撰寫程式碼的註解,就是給人看的東西筆記註解等等。 單行的註解使用(//) > single-line comment, you can use two slash characters (//) and then the comment text after it. ```javascript= let accountBalance = calculateBalance(account); // It's a green hollow where a river sings accountBalance.adjust(); // Madly catching white tatters in the grass. let report = new Report(); // Where the sun on the proud mountain rings: addToReport(accountBalance, report); // It's a little valley, foaming like light in a glass. ``` 多行的註解使用(/*and*/) ```javascript= /* I first found this number scrawled on the back of an old notebook. Since then, it has often dropped by, showing up in phone numbers and the serial numbers of products that I've bought. It obviously likes me, so I've decided to keep it. */ const myNumber = 11213; ``` ## Summary 從本章節可以明白程式是從很多的statements建構出來的,然後statement之中通常包含了一些expression,然後之中又可以包裹著一些更小的expression。 一行一行的statement是從頭到尾照順序執行的,在這行進之間又可以使用一些流程控制藉著: using conditional (if, else, and switch) 以及looping (while, do, and for) statements. Bindings 可以整理資料藉著命名的方式,同時也因此很好被追蹤。 The environment 是一組很多binding被定義的環境。js常常放入不少實用的標準化的binding在environment之中。 functions 是個特別的value,封裝了一些程式在裏頭,通常可以invoking它藉著functionName(argument1, argument2)這樣的方式來使用,這樣的function call是一個 expression同時可以產生valre ## Exercises ### Looping a triangle 使用loop做出下面那些 ``` javascript= # ## ### #### ##### ###### ####### ``` 解答: 這題我解的跟課本差不多 想了老半天沒辦法把字串混進去裡面,結果重點是Length處理進去讓他跑七次就好了,我一開始被混淆一直在想string轉換成number想了大概半小時,後來一直看length那邊才慢慢解出來。 ```javascript= for (let abc = "#"; abc.length <= 7; abc += "#" ) { console.log(abc);} ``` ### FizzBuzz 題目是: 排出1~100的數字,整除3的跑出Fizz,整除5的跑出Buzz,兩個都整除的數字跑出FizzBuzz 我的解法是先使用for 設定好跑出1~100,然後中間設定條件,甚麼情況跑出甚麼不是的話則正常跑出數字這樣。 ``` javascript= for (let a = 1; a <= 100; a++){ if (a % 15 === 0) { console.log("FizzBuzz"); } else if (a % 3 === 0) { console.log("Fizz");} else if (a % 5 === 0) { console.log("Buzz");} else { console.log(a); } } ``` 課本的漂亮解法: 一樣設定for 列出1~100,裡面包裹的地方再次設定output = " "; 然後一樣使用if做解題,這邊因為output是空白所以直接 += 字串填入符合條件的地方 output = " "+Fizz or Buzz 這樣去跑,都有整除的狀況下就跑兩個字串合併"FizzBuzz"快速簡潔。 ``` javascript= for (let n = 1; n <= 100; n++) { let output = ""; if (n % 3 == 0) output += "Fizz"; if (n % 5 == 0) output += "Buzz"; console.log(output || n); } ``` ### Chessboard 輸出個下方棋盤出來 好難放棄看解答 ``` javascript= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ``` 看不是很懂先跳過 ``` javascript= let size = 8; let board = ""; for (let y = 0; y < size; y++) { for (let x = 0; x < size; x++) { if ((x + y) % 2 == 0) { board += " "; } else { board += "#"; } } board += "\n"; } console.log(board); ```