# JS(3/10) Day 14 五倍紅寶石(第八屆共筆)(2021/7/15) ## 函式: 引數帶到參數會變變數。 參數寫在 function 裡 JS 會自動幫你在 function 內宣告,而且也不會洩漏出去。 如果要印出沒有定義的變數會出錯(not define)。 單純賦值的話會往外找有沒有一樣名稱的變數,沒有的話 JS 就直接在全域物件(最大泡泡)幫你宣告一個。 在JS裡,參數跟引數的數量不一樣不會出錯,別的程式語言則會。 引數 < 參數:沒被給到引數的參數會變 undefined。 引數 > 參數:多給的引數沒作用,不會印出。 function 在設定參數時也可以設定他的預設值。 當他沒有給引數時,他會自動帶入預設值。 ex:console.log()的預設值就是換行。 在function內輸入 console.log(arguments) 會以陣列方式直接印出所有引數。 寫code時盡量不要使用 ! ,因為要轉個彎會比較難理解。 a() = 呼叫a這個東西所指向的 function, ()只能用來呼叫 function ,若 a 指向的東西不是 function 會出錯。 --- ### 三種 function 寫法: 1. Function statement (Function declaration): function a( ) { } 2. Function expression: let b = function a( ) { } 3. Arrow function expressions: let b = ( ) => { } - 箭頭函式跟前面兩個函式是不同的函式,不是簡寫而已。 差異可參考:[Arrow function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) - 箭頭函式不能幫他取函式名,只能幫他取變數名字,不然會出錯。 - let b 可以省略,會變成匿名函式。 - ()內若只有一個參數可省略(),但不建議。 - 若{}裡面只有一行可省略{},並省略 return,但如果寫了{}就一定要加 return。 - 沒有自己的 this。 - 不能用 new 來建立。 - 沒有 .prototype 屬性。 - 當成建構物件來使用時,{}外面要再加()才能運作。 - => 一定要跟在()後面,可以空格但不能換行。 第一種的 a 不可省,第二種的可以省,省略後稱做匿名函式,因為一省略就沒名字呼叫啦,二前面已經宣告過一個 b 變數,之後的呼叫都靠他就好。(Kyle Simpson 大師很注重裡面的 function 名稱不能省略,有興趣的可以參考他的書。) --- ### function也會變數提升: 除了用 var、let、const 宣告會有變數提升的效果外,**Function declaration**也會這招,Function expression 跟 Arrow 因為是用變數宣告的關係,所以用法跟變數提升一樣。 其中 Function declaration 的提升跟變數的提升有一個地方不一樣。 回憶一下之前的變數提升有兩階段: 1. 建立期:JS會先分配記憶體給宣告的變數及函式,其中函式又會比變數優先被宣告, 在建立期會做兩件事情: 1A:註冊名稱 = 建立罐子,JS會執行宣告變數,但不會給變數的值。 1B:初始化 = 給他空氣,因為沒有值的關係,這個變數的值會是undefined。 2. 執行期:由上而下一行一行執行程式碼 在執行期會依照上至下的順序做兩件事情: 2A:把宣告變數裡的值指定給變數。 2B:執行函式。 Function declaration 的提升在建立期一樣會做1A、1B,但是不一樣的地方在於他還會在建立期多做2A。為的是方便輸出,因為函式之間常常互相呼叫,可以避免因為 b 函式寫在 a 函式下方的時候,用 a 無法呼叫 b 的狀況出現。 ```js= // 可正常執行 function a( ) {b() } function b( ) { } ``` --- ### scope chain: 指派的特權,如果在函式內的變數只有指派而沒有宣告(ex: a = 1),會往函式外去找這個變數有沒有宣告,都找不到的話JS最後會直接在全域物件裡幫你宣告一個。(別的程式語言不會這樣) 若最後有找到變數會污染他,讓他變成自己的值。 全域物件:node.js 叫 global,瀏覽器叫 window。 console.log 的全名應該叫 window.console.log。 --- ### 變數存活範圍: function 裡的變數宣告只能活在那個 function 裡,執行完泡泡就會破了。 function{}可以關住:var、let、const。 {}只能關住:let、const。 for(var...){} 會溢出到外面。 for(let...){} 因為有{}所以會鎖在 scope 裡。 ```js= // 建議寫法:把宣告 result 拉到 for 迴圈外面並且不指定值,才不會被鎖在裡面。 let age =20 let result if (age >= 18) { result = "已成年" } else { result = "未成年" } console.log(result) ``` --- ## 物件: ```js= const hero = {name(key):"悟空"(value)} 可以用 console.log(hero.name)或是 console.log(hero["name"])來呼叫 ``` ### Xmind: [JavaScript指令](https://www.xmind.net/m/eYMwp5) --- ###### tags: `JavaScript`